aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts7
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx83
-rw-r--r--src/client/views/nodes/DocumentView.tsx2
3 files changed, 87 insertions, 5 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 17e474e0e..09bafcf43 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -603,9 +603,8 @@ export namespace DocUtils {
let linkDoc: Doc | undefined;
UndoManager.RunInBatch(() => {
- linkDoc = Docs.Create.TextDocument({ width: 100, height: 30, borderRounding: "100%" });
- linkDoc.type = DocumentType.LINK;
- let linkDocProto = Doc.GetProto(linkDoc);
+ let linkDocProto = new Doc();
+ linkDocProto.type = DocumentType.LINK;
linkDocProto.targetContext = targetContext;
linkDocProto.sourceContext = sourceContext;
@@ -621,7 +620,7 @@ export namespace DocUtils {
linkDocProto.anchor2Page = target.curPage;
linkDocProto.anchor2Groups = new List<Doc>([]);
- LinkManager.Instance.addLink(linkDoc);
+ LinkManager.Instance.addLink(linkDocProto);
let script = `return links(this)};`;
let computed = CompileScript(script, { params: { this: "Doc" }, typecheck: false });
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 90f67c54e..232ac22c9 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -127,7 +127,25 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
return Doc.resolvedFieldDataDoc(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey, "true");
}
-
+ intersectRect(r1: { left: number, top: number, width: number, height: number },
+ r2: { left: number, top: number, width: number, height: number }) {
+ return !(r2.left > r1.left + r1.width || r2.left + r2.width < r1.left || r2.top > r1.top + r1.height || r2.top + r2.height < r1.top);
+ }
+ _groupingBorder = 100;
+ bounsdSelect(doc: Doc, doc2: Doc) {
+ var x2 = NumCast(doc2.x) - this._groupingBorder;
+ var y2 = NumCast(doc2.y) - this._groupingBorder;
+ var w2 = NumCast(doc2.width) + this._groupingBorder;
+ var h2 = NumCast(doc2.height) + this._groupingBorder;
+ var x = NumCast(doc.x) - this._groupingBorder;
+ var y = NumCast(doc.y) - this._groupingBorder;
+ var w = NumCast(doc.width) + this._groupingBorder;
+ var h = NumCast(doc.height) + this._groupingBorder;
+ if (this.intersectRect({ left: x, top: y, width: w, height: h }, { left: x2, top: y2, width: w2, height: h2 })) {
+ return true;
+ }
+ return false;
+ }
@undoBatch
@action
drop = (e: Event, de: DragManager.DropEvent) => {
@@ -156,6 +174,35 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
}
this.bringToFront(d);
});
+
+ let sets: (Doc[])[] = []
+ this.childDocs.map(c => {
+ let included = []
+ for (let i = 0; i < sets.length; i++) {
+ for (let j = 0; j < sets[i].length; j++) {
+ if (this.bounsdSelect(c, sets[i][j])) {
+ included.push(i);
+ break;
+ }
+ }
+ }
+ if (included.length === 0)
+ sets.push([c]);
+ else if (included.length === 1)
+ sets[included[0]].push(c);
+ else {
+ sets[included[0]].push(c);
+ for (let s = 1; s < included.length; s++) {
+ sets[included[0]].push(...sets[included[s]]);
+ sets[included[s]].length = 0;
+ }
+ }
+ });
+ for (let s = 0; s < sets.length; s++) {
+ for (let i = 0; i < sets[s].length; i++) {
+ Doc.GetProto(sets[s][i]).cluster = s;
+ }
+ }
}
}
else if (de.data instanceof DragManager.AnnotationDragData) {
@@ -196,6 +243,40 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
@action
onPointerMove = (e: PointerEvent): void => {
if (!e.cancelBubble) {
+ let probe = this.getTransform().transformPoint(e.clientX, e.clientY);
+ let cluster = this.childDocs.reduce((cluster, cd) => {
+ let cx = NumCast(cd.x) - this._groupingBorder;
+ let cy = NumCast(cd.y) - this._groupingBorder;
+ let cw = NumCast(cd.width) + this._groupingBorder;
+ let ch = NumCast(cd.height) + this._groupingBorder;
+ if (this.intersectRect({ left: cx, top: cy, width: cw, height: ch }, { left: probe[0], top: probe[1], width: 1, height: 1 }))
+ return NumCast(cd.cluster);
+ return cluster;
+ }, -1);
+ if (cluster !== -1) {
+ let eles = this.childDocs.filter(cd => NumCast(cd.cluster) === cluster);
+ this.selectDocuments(eles);
+ let clusterDocs = SelectionManager.SelectedDocuments();
+ SelectionManager.DeselectAll();
+ let de = new DragManager.DocumentDragData(eles, eles.map(d => undefined));
+ de.moveDocument = this.props.moveDocument;
+ const [left, top] = clusterDocs[0].props.ScreenToLocalTransform().scale(clusterDocs[0].props.ContentScaling()).inverse().transformPoint(0, 0);
+ const [xoff, yoff] = this.getTransform().transformDirection(e.x - left, e.y - top);
+ de.dropAction = e.ctrlKey || e.altKey ? "alias" : undefined;
+ de.xOffset = xoff;
+ de.yOffset = yoff;
+ DragManager.StartDocumentDrag(clusterDocs.map(v => v.ContentDiv!), de, e.clientX, e.clientY, {
+ handlers: {
+ dragComplete: action(emptyFunction)
+ },
+ hideSource: !de.dropAction
+ });
+ e.stopPropagation(); // doesn't actually stop propagation since all our listeners are listening to events on 'document' however it does mark the event as cancelBubble=true which we test for in the move event handlers
+ e.preventDefault();
+ document.removeEventListener("pointermove", this.onPointerMove);
+ document.removeEventListener("pointerup", this.onPointerUp);
+ return;
+ }
let x = this.Document.panX || 0;
let y = this.Document.panY || 0;
let docs = this.childDocs || [];
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 45b5c328c..d79b58a7b 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -695,6 +695,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
});
}
let showTextTitle = showTitle && StrCast(this.layoutDoc.layout).startsWith("<FormattedTextBox") ? showTitle : undefined;
+ let colors = ["#da42429e", "#31ea318c", "#4a7ae2c4", "#d809ff", "#ff7601", "#1dffff", "#000000ad"];
return (
<div className={`documentView-node${this.topMost ? "-topmost" : ""}`}
ref={this._mainCont}
@@ -703,6 +704,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
color: foregroundColor,
outlineColor: "maroon",
outlineStyle: "dashed",
+ boxShadow: `${colors[NumCast(this.props.Document.cluster) % colors.length]} ${StrCast(this.props.Document.boxShadow, `0vw 0vw ${50 / this.props.ContentScaling()}px`)}`,
outlineWidth: BoolCast(this.layoutDoc.libraryBrush) && !StrCast(Doc.GetProto(this.props.Document).borderRounding) ?
`${this.props.ScreenToLocalTransform().Scale}px` : "0px",
marginLeft: BoolCast(this.layoutDoc.libraryBrush) && StrCast(Doc.GetProto(this.props.Document).borderRounding) ?