aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/collectionFreeForm
diff options
context:
space:
mode:
authorAbdullah Ahmed <abdullah_ahmed@brown.edu>2019-10-19 14:41:16 -0400
committerAbdullah Ahmed <abdullah_ahmed@brown.edu>2019-10-19 14:41:16 -0400
commit1a8292f7588880718a657a5fca5c32f1a5975205 (patch)
tree216639d9d5387ba2563b37b169c678301d671b15 /src/client/views/collections/collectionFreeForm
parent5e04d7f94d180dc984e48eca888ac2cedfd0c7a3 (diff)
parent3d910bae8771e67cabc1500c49b77d425fdf62e9 (diff)
merged
Diffstat (limited to 'src/client/views/collections/collectionFreeForm')
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss3
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx81
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.scss5
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx69
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx135
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx31
6 files changed, 122 insertions, 202 deletions
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss
index cfd18ad35..1f1bca2f2 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss
@@ -1,6 +1,5 @@
.collectionfreeformlinkview-linkLine {
stroke: black;
- transform: translate(10000px,10000px);
opacity: 0.8;
pointer-events: all;
stroke-width: 3px;
@@ -8,13 +7,11 @@
.collectionfreeformlinkview-linkCircle {
stroke: rgb(0,0,0);
opacity: 0.5;
- transform: translate(10000px,10000px);
pointer-events: all;
cursor: pointer;
}
.collectionfreeformlinkview-linkText {
stroke: rgb(0,0,0);
opacity: 0.5;
- transform: translate(10000px,10000px);
pointer-events: all;
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index df089eb00..962fe2a1c 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -1,63 +1,48 @@
import { observer } from "mobx-react";
-import { Doc, HeightSym, WidthSym } from "../../../../new_fields/Doc";
-import { BoolCast, NumCast, StrCast } from "../../../../new_fields/Types";
-import { InkingControl } from "../../InkingControl";
+import { Doc } from "../../../../new_fields/Doc";
+import { Utils } from '../../../../Utils';
+import { DocumentView } from "../../nodes/DocumentView";
import "./CollectionFreeFormLinkView.scss";
import React = require("react");
import v5 = require("uuid/v5");
+import { DocumentType } from "../../../documents/DocumentTypes";
+import { observable, action } from "mobx";
export interface CollectionFreeFormLinkViewProps {
- A: Doc;
- B: Doc;
+ A: DocumentView;
+ B: DocumentView;
LinkDocs: Doc[];
- addDocument: (document: Doc, allowDuplicates?: boolean) => boolean;
- removeDocument: (document: Doc) => boolean;
}
@observer
export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFormLinkViewProps> {
-
- onPointerDown = (e: React.PointerEvent) => {
- if (e.button === 0 && !InkingControl.Instance.selectedTool) {
- let a = this.props.A;
- let b = this.props.B;
- let x1 = NumCast(a.x) + (BoolCast(a.isMinimized) ? 5 : a[WidthSym]() / 2);
- let y1 = NumCast(a.y) + (BoolCast(a.isMinimized) ? 5 : a[HeightSym]() / 2);
- let x2 = NumCast(b.x) + (BoolCast(b.isMinimized) ? 5 : b[WidthSym]() / 2);
- let y2 = NumCast(b.y) + (BoolCast(b.isMinimized) ? 5 : b[HeightSym]() / 2);
- // this.props.LinkDocs.map(l => {
- // let width = l[WidthSym]();
- // l.x = (x1 + x2) / 2 - width / 2;
- // l.y = (y1 + y2) / 2 + 10;
- // if (!this.props.removeDocument(l)) this.props.addDocument(l, false);
- // });
- e.stopPropagation();
- e.preventDefault();
- }
+ @observable _alive: number = 0;
+ @action
+ componentDidMount() {
+ this._alive = 1;
+ setTimeout(this.rerender, 50);
+ }
+ @action
+ componentWillUnmount() {
+ this._alive = 0;
}
+ rerender = action(() => {
+ if (this._alive) {
+ setTimeout(this.rerender, 50);
+ this._alive++;
+ }
+ });
+
render() {
- // let l = this.props.LinkDocs;
- let a = this.props.A;
- let b = this.props.B;
- let x1 = NumCast(a.x) + (BoolCast(a.isMinimized, false) ? 5 : NumCast(a.width) / 2);
- let y1 = NumCast(a.y) + (BoolCast(a.isMinimized, false) ? 5 : NumCast(a.height) / 2);
- let x2 = NumCast(b.x) + (BoolCast(b.isMinimized, false) ? 5 : NumCast(b.width) / 2);
- let y2 = NumCast(b.y) + (BoolCast(b.isMinimized, false) ? 5 : NumCast(b.height) / 2);
- let text = "";
- // let first = this.props.LinkDocs[0];
- // if (this.props.LinkDocs.length === 1) text += first.title + (first.linkDescription ? "(" + StrCast(first.linkDescription) + ")" : "");
- // else text = "-multiple-";
- return (
- <>
- <line key="linkLine" className="collectionfreeformlinkview-linkLine"
- x1={`${x1}`} y1={`${y1}`}
- x2={`${x2}`} y2={`${y2}`} />
- {/* <circle key="linkCircle" className="collectionfreeformlinkview-linkCircle"
- cx={(x1 + x2) / 2} cy={(y1 + y2) / 2} r={8} onPointerDown={this.onPointerDown} /> */}
- <text key="linkText" textAnchor="middle" className="collectionfreeformlinkview-linkText" x={`${(x1 + x2) / 2}`} y={`${(y1 + y2) / 2}`}>
- {text}
- </text>
- </>
- );
+ let y = this._alive;
+ let acont = this.props.A.props.Document.type === DocumentType.LINK ? this.props.A.ContentDiv!.getElementsByClassName("docuLinkBox-cont") : [];
+ let bcont = this.props.B.props.Document.type === DocumentType.LINK ? this.props.B.ContentDiv!.getElementsByClassName("docuLinkBox-cont") : [];
+ let a = (acont.length ? acont[0] : this.props.A.ContentDiv!).getBoundingClientRect();
+ let b = (bcont.length ? bcont[0] : this.props.B.ContentDiv!).getBoundingClientRect();
+ let pt1 = Utils.getNearestPointInPerimeter(a.left, a.top, a.width, a.height, b.left + b.width / 2, b.top + b.height / 2);
+ let pt2 = Utils.getNearestPointInPerimeter(b.left, b.top, b.width, b.height, a.left + a.width / 2, a.top + a.height / 2);
+ return (<line key="linkLine" className="collectionfreeformlinkview-linkLine"
+ x1={`${pt1[0]}`} y1={`${pt1[1]}`}
+ x2={`${pt2[0]}`} y2={`${pt2[1]}`} />);
}
} \ No newline at end of file
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.scss
index 30e158603..cb5cef29c 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.scss
@@ -1,10 +1,9 @@
.collectionfreeformlinksview-svgCanvas{
- transform: translate(-10000px,-10000px);
position: absolute;
top: 0;
left: 0;
- width: 20000px;
- height: 20000px;
+ width: 100%;
+ height: 100%;
pointer-events: none;
}
.collectionfreeformlinksview-container {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
index a81f5315a..e9191c176 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
@@ -1,19 +1,18 @@
-import { computed, IReactionDisposer, reaction } from "mobx";
+import { computed, IReactionDisposer } from "mobx";
import { observer } from "mobx-react";
-import { Doc, DocListCast } from "../../../../new_fields/Doc";
+import { Doc } from "../../../../new_fields/Doc";
import { Id } from "../../../../new_fields/FieldSymbols";
-import { List } from "../../../../new_fields/List";
-import { listSpec } from "../../../../new_fields/Schema";
-import { Cast, FieldValue, NumCast, StrCast } from "../../../../new_fields/Types";
import { DocumentManager } from "../../../util/DocumentManager";
import { DocumentView } from "../../nodes/DocumentView";
-import { CollectionViewProps } from "../CollectionSubView";
import "./CollectionFreeFormLinksView.scss";
import { CollectionFreeFormLinkView } from "./CollectionFreeFormLinkView";
import React = require("react");
+import { Utils } from "../../../../Utils";
+import { SelectionManager } from "../../../util/SelectionManager";
+import { DocumentType } from "../../../documents/DocumentTypes";
@observer
-export class CollectionFreeFormLinksView extends React.Component<CollectionViewProps> {
+export class CollectionFreeFormLinksView extends React.Component {
_brushReactionDisposer?: IReactionDisposer;
componentDidMount() {
@@ -69,59 +68,33 @@ export class CollectionFreeFormLinksView extends React.Component<CollectionViewP
// });
}
componentWillUnmount() {
- if (this._brushReactionDisposer) {
- this._brushReactionDisposer();
- }
+ this._brushReactionDisposer && this._brushReactionDisposer();
}
- documentAnchors(view: DocumentView) {
- let equalViews = [view];
- let containerDoc = FieldValue(Cast(view.props.Document.annotationOn, Doc));
- if (containerDoc) {
- equalViews = DocumentManager.Instance.getDocumentViews(containerDoc.proto!);
- }
- if (view.props.ContainingCollectionDoc) {
- let collid = view.props.ContainingCollectionDoc[Id];
- DocListCast(this.props.Document[this.props.fieldKey]).
- filter(child =>
- child[Id] === collid).map(view =>
- DocumentManager.Instance.getDocumentViews(view).map(view =>
- equalViews.push(view)));
- }
- return equalViews.filter(sv => sv.props.ContainingCollectionDoc === this.props.Document);
- }
-
@computed
get uniqueConnections() {
let connections = DocumentManager.Instance.LinkedDocumentViews.reduce((drawnPairs, connection) => {
- let srcViews = this.documentAnchors(connection.a);
- let targetViews = this.documentAnchors(connection.b);
-
- let possiblePairs: { a: Doc, b: Doc, }[] = [];
- srcViews.map(sv => targetViews.map(tv => possiblePairs.push({ a: sv.props.Document, b: tv.props.Document })));
- possiblePairs.map(possiblePair => {
- if (!drawnPairs.reduce((found, drawnPair) => {
- let match1 = (Doc.AreProtosEqual(possiblePair.a, drawnPair.a) && Doc.AreProtosEqual(possiblePair.b, drawnPair.b));
- let match2 = (Doc.AreProtosEqual(possiblePair.a, drawnPair.b) && Doc.AreProtosEqual(possiblePair.b, drawnPair.a));
- let match = match1 || match2;
- if (match && !drawnPair.l.reduce((found, link) => found || link[Id] === connection.l[Id], false)) {
- drawnPair.l.push(connection.l);
- }
- return match || found;
- }, false)) {
- drawnPairs.push({ a: possiblePair.a, b: possiblePair.b, l: [connection.l] });
+ if (!drawnPairs.reduce((found, drawnPair) => {
+ let match1 = (connection.a === drawnPair.a && connection.b === drawnPair.b);
+ let match2 = (connection.a === drawnPair.b && connection.b === drawnPair.a);
+ let match = match1 || match2;
+ if (match && !drawnPair.l.reduce((found, link) => found || link[Id] === connection.l[Id], false)) {
+ drawnPair.l.push(connection.l);
}
- });
+ return match || found;
+ }, false)) {
+ drawnPairs.push({ a: connection.a, b: connection.b, l: [connection.l] });
+ }
return drawnPairs;
- }, [] as { a: Doc, b: Doc, l: Doc[] }[]);
- return connections.map(c => <CollectionFreeFormLinkView key={c.l.reduce((p, l) => p + l[Id], "")} A={c.a} B={c.b} LinkDocs={c.l}
- removeDocument={this.props.removeDocument} addDocument={this.props.addDocument} />);
+ }, [] as { a: DocumentView, b: DocumentView, l: Doc[] }[]);
+ return connections.filter(c => c.a.props.Document.type === DocumentType.LINK) // get rid of the filter to show links to documents in addition to document anchors
+ .map(c => <CollectionFreeFormLinkView key={Utils.GenerateGuid()} A={c.a} B={c.b} LinkDocs={c.l} />);
}
render() {
return (
<div className="collectionfreeformlinksview-container">
<svg className="collectionfreeformlinksview-svgCanvas">
- {this.uniqueConnections}
+ {SelectionManager.GetIsDragging() ? (null) : this.uniqueConnections}
</svg>
{this.props.children}
</div>
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index d2b8afa02..e421879da 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,6 +1,6 @@
import { library } from "@fortawesome/fontawesome-svg-core";
import { faEye } from "@fortawesome/free-regular-svg-icons";
-import { faBraille, faChalkboard, faCompass, faCompressArrowsAlt, faExpandArrowsAlt, faPaintBrush, faTable, faUpload, faFileUpload } from "@fortawesome/free-solid-svg-icons";
+import { faBraille, faChalkboard, faCompass, faCompressArrowsAlt, faExpandArrowsAlt, faFileUpload, faPaintBrush, faTable, faUpload } from "@fortawesome/free-solid-svg-icons";
import { action, computed, observable } from "mobx";
import { observer } from "mobx-react";
import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../../new_fields/Doc";
@@ -28,7 +28,6 @@ import { CollectionFreeFormDocumentView, positionSchema } from "../../nodes/Coll
import { DocumentContentsView } from "../../nodes/DocumentContentsView";
import { documentSchema, DocumentViewProps } from "../../nodes/DocumentView";
import { pageSchema } from "../../nodes/ImageBox";
-import PDFMenu from "../../pdf/PDFMenu";
import { CollectionSubView } from "../CollectionSubView";
import { computePivotLayout, ViewDefResult } from "./CollectionFreeFormLayoutEngines";
import { CollectionFreeFormLinksView } from "./CollectionFreeFormLinksView";
@@ -98,10 +97,10 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
heading = !sorted.length ? Math.max(1, maxHeading) : NumCast(sorted[sorted.length - 1].heading) === 1 ? 2 : NumCast(sorted[sorted.length - 1].heading);
}
!this.Document.isRuleProvider && (newBox.heading = heading);
- this.addDocument(newBox, false);
+ this.addDocument(newBox);
}
- private addDocument = (newBox: Doc, allowDuplicates: boolean) => {
- let added = this.props.addDocument(newBox, false);
+ private addDocument = (newBox: Doc) => {
+ let added = this.props.addDocument(newBox);
added && this.bringToFront(newBox);
added && this.updateCluster(newBox);
return added;
@@ -136,21 +135,23 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
if (super.drop(e, de)) {
if (de.data instanceof DragManager.DocumentDragData) {
if (de.data.droppedDocuments.length) {
- let z = NumCast(de.data.droppedDocuments[0].z);
+ let firstDoc = de.data.droppedDocuments[0];
+ let z = NumCast(firstDoc.z);
let x = (z ? xpo : xp) - de.data.offset[0];
let y = (z ? ypo : yp) - de.data.offset[1];
- let dropX = NumCast(de.data.droppedDocuments[0].x);
- let dropY = NumCast(de.data.droppedDocuments[0].y);
+ let dropX = NumCast(firstDoc.x);
+ let dropY = NumCast(firstDoc.y);
de.data.droppedDocuments.forEach(action((d: Doc) => {
+ let layoutDoc = Doc.Layout(d);
d.x = x + NumCast(d.x) - dropX;
d.y = y + NumCast(d.y) - dropY;
- if (!NumCast(d.width)) {
- d.width = 300;
+ if (!NumCast(layoutDoc.width)) {
+ layoutDoc.width = 300;
}
- if (!NumCast(d.height)) {
- let nw = NumCast(d.nativeWidth);
- let nh = NumCast(d.nativeHeight);
- d.height = nw && nh ? nh / nw * NumCast(d.width) : 300;
+ if (!NumCast(layoutDoc.height)) {
+ let nw = NumCast(layoutDoc.nativeWidth);
+ let nh = NumCast(layoutDoc.nativeHeight);
+ layoutDoc.height = nw && nh ? nh / nw * NumCast(layoutDoc.width) : 300;
}
this.bringToFront(d);
}));
@@ -163,12 +164,11 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
let dragDoc = de.data.dropDocument;
let x = xp - de.data.offset[0];
let y = yp - de.data.offset[1];
- let dropX = NumCast(de.data.dropDocument.x);
- let dropY = NumCast(de.data.dropDocument.y);
+ let dropX = NumCast(dragDoc.x);
+ let dropY = NumCast(dragDoc.y);
dragDoc.x = x + NumCast(dragDoc.x) - dropX;
dragDoc.y = y + NumCast(dragDoc.y) - dropY;
- de.data.targetContext = this.props.Document;
- dragDoc.targetContext = this.props.Document;
+ de.data.targetContext = this.props.Document; // dropped a PDF annotation, so we need to set the targetContext on the dragData which the PDF view uses at the end of the drop operation
this.bringToFront(dragDoc);
}
}
@@ -178,11 +178,12 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
pickCluster(probe: number[]) {
return this.childLayoutPairs.map(pair => pair.layout).reduce((cluster, cd) => {
+ let layoutDoc = Doc.Layout(cd);
let cx = NumCast(cd.x) - this._clusterDistance;
let cy = NumCast(cd.y) - this._clusterDistance;
- let cw = NumCast(cd.width) + 2 * this._clusterDistance;
- let ch = NumCast(cd.height) + 2 * this._clusterDistance;
- return !cd.z && intersectRect({ left: cx, top: cy, width: cw, height: ch }, { left: probe[0], top: probe[1], width: 1, height: 1 }) ?
+ let cw = NumCast(layoutDoc.width) + 2 * this._clusterDistance;
+ let ch = NumCast(layoutDoc.height) + 2 * this._clusterDistance;
+ return !layoutDoc.z && intersectRect({ left: cx, top: cy, width: cw, height: ch }, { left: probe[0], top: probe[1], width: 1, height: 1 }) ?
NumCast(cd.cluster) : cluster;
}, -1);
}
@@ -190,14 +191,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
let cluster = this.pickCluster(this.getTransform().transformPoint(e.clientX, e.clientY));
if (cluster !== -1) {
let eles = this.childLayoutPairs.map(pair => pair.layout).filter(cd => NumCast(cd.cluster) === cluster);
-
- // hacky way to get a list of DocumentViews in the current view given a list of Documents in the current view
- let prevSelected = SelectionManager.SelectedDocuments();
- this.selectDocuments(eles);
- let clusterDocs = SelectionManager.SelectedDocuments();
- SelectionManager.DeselectAll();
- prevSelected.map(dv => SelectionManager.SelectDoc(dv, true));
-
+ let clusterDocs = eles.map(ele => DocumentManager.Instance.getDocumentView(ele, this.props.CollectionView)!);
let de = new DragManager.DocumentDragData(eles);
de.moveDocument = this.props.moveDocument;
const [left, top] = clusterDocs[0].props.ScreenToLocalTransform().scale(clusterDocs[0].props.ContentScaling()).inverse().transformPoint(0, 0);
@@ -291,7 +285,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
@action
onPointerMove = (e: PointerEvent): void => {
- if (!e.cancelBubble && !this.isAnnotationOverlay) {
+ if (!e.cancelBubble) {
if (this._hitCluster && this.tryDragCluster(e)) {
e.stopPropagation(); // doesn't actually stop propagation since all our listeners are listening to events on 'document' however it does mark the event as cancelBubble=true which we test for in the move event handlers
e.preventDefault();
@@ -304,16 +298,16 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
let docs = this.childLayoutPairs.map(pair => pair.layout);
let [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
if (!this.isAnnotationOverlay) {
- PDFMenu.Instance.fadeOut(true);
let minx = docs.length ? NumCast(docs[0].x) : 0;
- let maxx = docs.length ? NumCast(docs[0].width) + minx : minx;
+ let maxx = docs.length ? NumCast(Doc.Layout(docs[0]).width) + minx : minx;
let miny = docs.length ? NumCast(docs[0].y) : 0;
- let maxy = docs.length ? NumCast(docs[0].height) + miny : miny;
+ let maxy = docs.length ? NumCast(Doc.Layout(docs[0]).height) + miny : miny;
let ranges = docs.filter(doc => doc).reduce((range, doc) => {
+ let layoutDoc = Doc.Layout(doc);
let x = NumCast(doc.x);
- let xe = x + NumCast(doc.width);
+ let xe = x + NumCast(layoutDoc.width);
let y = NumCast(doc.y);
- let ye = y + NumCast(doc.height);
+ let ye = y + NumCast(layoutDoc.height);
return [[range[0][0] > x ? x : range[0][0], range[0][1] < xe ? xe : range[0][1]],
[range[1][0] > y ? y : range[1][0], range[1][1] < ye ? ye : range[1][1]]];
}, [[minx, maxx], [miny, maxy]]);
@@ -344,7 +338,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
@action
onPointerWheel = (e: React.WheelEvent): void => {
- if (this.props.Document.lockedPosition || this.props.Document.inOverlay || this.isAnnotationOverlay) return;
+ if (this.props.Document.lockedPosition || this.props.Document.inOverlay) return;
if (!e.ctrlKey && this.props.Document.scrollHeight !== undefined) { // things that can scroll vertically should do that instead of zooming
e.stopPropagation();
}
@@ -417,8 +411,9 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
this.props.Document.scrollY = NumCast(doc.y) - offset;
}
} else {
- const newPanX = NumCast(doc.x) + NumCast(doc.width) / 2;
- const newPanY = NumCast(doc.y) + NumCast(doc.height) / 2;
+ let layoutdoc = Doc.Layout(doc);
+ const newPanX = NumCast(doc.x) + NumCast(layoutdoc.width) / 2;
+ const newPanY = NumCast(doc.y) + NumCast(layoutdoc.height) / 2;
const newState = HistoryUtil.getState();
newState.initializers![this.Document[Id]] = { panX: newPanX, panY: newPanY };
HistoryUtil.pushState(newState);
@@ -429,7 +424,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
this.Document.panTransformType = "Ease";
Doc.BrushDoc(this.props.Document);
this.props.focus(this.props.Document);
- willZoom && this.setScaleToZoom(doc, scale);
+ willZoom && this.setScaleToZoom(layoutdoc, scale);
afterFocus && setTimeout(() => {
if (afterFocus && afterFocus()) {
@@ -475,30 +470,15 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
getScale: this.getScale
};
}
- getDocumentViewProps(layoutDoc: Doc): DocumentViewProps {
- return {
- ...this.props,
- ScreenToLocalTransform: this.getTransform,
- PanelWidth: layoutDoc[WidthSym],
- PanelHeight: layoutDoc[HeightSym],
- ContentScaling: returnOne,
- ContainingCollectionView: this.props.CollectionView,
- focus: this.focusDocument,
- backgroundColor: returnEmptyString,
- parentActive: this.props.active,
- bringToFront: this.bringToFront,
- zoomToScale: this.zoomToScale,
- getScale: this.getScale
- };
- }
getCalculatedPositions(params: { doc: Doc, index: number, collection: Doc, docs: Doc[], state: any }): { x?: number, y?: number, z?: number, width?: number, height?: number, transition?: string, state?: any } {
const script = this.Document.arrangeScript;
const result = script && script.script.run(params, console.log);
+ const layoutDoc = Doc.Layout(params.doc);
if (result && result.success) {
return { ...result, transition: "transform 1s" };
}
- return { x: Cast(params.doc.x, "number"), y: Cast(params.doc.y, "number"), z: Cast(params.doc.z, "number"), width: Cast(params.doc.width, "number"), height: Cast(params.doc.height, "number") };
+ return { x: Cast(params.doc.x, "number"), y: Cast(params.doc.y, "number"), z: Cast(params.doc.z, "number"), width: Cast(layoutDoc.width, "number"), height: Cast(layoutDoc.height, "number") };
}
viewDefsToJSX = (views: any[]) => {
@@ -615,7 +595,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
// find rule colorations when rule providing is turned on by looking at each document to see if it has a coloring -- if so, use it's color as the rule for its associated heading.
this.Document.isRuleProvider && this.childLayoutPairs.map(pair =>
// iterate over the children of a displayed document (or if the displayed document is a template, iterate over the children of that template)
- DocListCast(pair.layout.layout instanceof Doc ? pair.layout.layout.data : pair.layout.data).map(heading => {
+ DocListCast(Doc.Layout(pair.layout).data).map(heading => {
let headingPair = Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, heading);
let headingLayout = headingPair.layout && (pair.layout.data_ext instanceof Doc) && (pair.layout.data_ext[`Layout[${headingPair.layout[Id]}]`] as Doc) || headingPair.layout;
if (headingLayout && NumCast(headingLayout.heading) > 0 && headingLayout.backgroundColor !== headingLayout.defaultBackgroundColor) {
@@ -635,7 +615,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
onContextMenu = (e: React.MouseEvent) => {
let layoutItems: ContextMenuProps[] = [];
- if (this.childDocs.some(d => BoolCast(d.isTemplate))) {
+ if (this.childDocs.some(d => BoolCast(d.isTemplateDoc))) {
layoutItems.push({ description: "Template Layout Instance", event: () => this.props.addDocTab(Doc.ApplyTemplate(this.props.Document)!, undefined, "onRight"), icon: "project-diagram" });
}
layoutItems.push({ description: "reset view", event: () => { this.props.Document.panX = this.props.Document.panY = 0; this.props.Document.scale = 1; }, icon: "compress-arrows-alt" });
@@ -664,7 +644,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
if (doc instanceof Doc) {
const [xx, yy] = this.props.ScreenToLocalTransform().transformPoint(x, y);
doc.x = xx, doc.y = yy;
- this.props.addDocument && this.props.addDocument(doc, false);
+ this.props.addDocument && this.props.addDocument(doc);
}
}
}
@@ -686,10 +666,13 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
}
- private childViews = () => [
- <CollectionFreeFormBackgroundView key="backgroundView" {...this.props} {...this.getDocumentViewProps(this.props.Document)} />,
- ...this.views
- ]
+ private childViews = () => {
+ let children = typeof this.props.children === "function" ? (this.props.children as any)() as JSX.Element[] : [];
+ return [
+ ...children,
+ ...this.views,
+ ];
+ }
render() {
// update the actual dimensions of the collection so that they can inquired (e.g., by a minimap)
this.props.Document.fitX = this.contentBounds && this.contentBounds.x;
@@ -708,38 +691,18 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
getContainerTransform={this.getContainerTransform} getTransform={this.getTransform} isAnnotationOverlay={this.isAnnotationOverlay}>
<CollectionFreeFormViewPannableContents centeringShiftX={this.centeringShiftX} centeringShiftY={this.centeringShiftY}
easing={this.easing} zoomScaling={this.zoomScaling} panX={this.panX} panY={this.panY}>
- <CollectionFreeFormLinksView {...this.props} key="freeformLinks">
- <InkingCanvas getScreenTransform={this.getTransform} Document={this.props.Document} AnnotationDocument={this.fieldExtensionDoc} inkFieldKey={"ink"} >
- {this.childViews}
- </InkingCanvas>
- </CollectionFreeFormLinksView>
+ <InkingCanvas getScreenTransform={this.getTransform} Document={this.props.Document} AnnotationDocument={this.fieldExtensionDoc} inkFieldKey={"ink"} >
+ {this.childViews}
+ </InkingCanvas>
<CollectionFreeFormRemoteCursors {...this.props} key="remoteCursors" />
</CollectionFreeFormViewPannableContents>
</MarqueeView>
{this.overlayViews}
- <CollectionFreeFormOverlayView {...this.props} {...this.getDocumentViewProps(this.props.Document)} />
</div>
);
}
}
-@observer
-class CollectionFreeFormOverlayView extends React.Component<DocumentViewProps & { isSelected: () => boolean }> {
- render() {
- return <DocumentContentsView {...this.props} layoutKey={"overlayLayout"}
- renderDepth={this.props.renderDepth} isSelected={this.props.isSelected} select={emptyFunction} />;
- }
-}
-
-@observer
-class CollectionFreeFormBackgroundView extends React.Component<DocumentViewProps & { isSelected: () => boolean }> {
- render() {
- return !this.props.Document.backgroundLayout ? (null) :
- (<DocumentContentsView {...this.props} layoutKey={"backgroundLayout"}
- renderDepth={this.props.renderDepth} isSelected={this.props.isSelected} select={emptyFunction} />);
- }
-}
-
interface CollectionFreeFormViewPannableContentsProps {
centeringShiftX: () => number;
centeringShiftY: () => number;
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index eaf65b88c..637168f1b 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -24,7 +24,7 @@ interface MarqueeViewProps {
getContainerTransform: () => Transform;
getTransform: () => Transform;
container: CollectionFreeFormView;
- addDocument: (doc: Doc, allowDuplicates: false) => boolean;
+ addDocument: (doc: Doc) => boolean;
activeDocuments: () => Doc[];
selectDocuments: (docs: Doc[]) => void;
removeDocument: (doc: Doc) => boolean;
@@ -83,7 +83,7 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
ns.map(line => {
let indent = line.search(/\S|$/);
let newBox = Docs.Create.TextDocument({ width: 200, height: 35, x: x + indent / 3 * 10, y: y, documentText: "@@@" + line, title: line });
- this.props.addDocument(newBox, false);
+ this.props.addDocument(newBox);
y += 40 * this.props.getTransform().Scale;
});
})();
@@ -92,7 +92,7 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
navigator.clipboard.readText().then(text => {
let ns = text.split("\n").filter(t => t.trim() !== "\r" && t.trim() !== "");
if (ns.length === 1 && text.startsWith("http")) {
- this.props.addDocument(Docs.Create.ImageDocument(text, { nativeWidth: 300, width: 300, x: x, y: y }), false);// paste an image from its URL in the paste buffer
+ this.props.addDocument(Docs.Create.ImageDocument(text, { nativeWidth: 300, width: 300, x: x, y: y }));// paste an image from its URL in the paste buffer
} else {
this.pasteTable(ns, x, y);
}
@@ -146,7 +146,7 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
}
let newCol = Docs.Create.SchemaDocument([...(groupAttr ? [new SchemaHeaderField("_group", "#f1efeb")] : []), ...columns.filter(c => c).map(c => new SchemaHeaderField(c, "#f1efeb"))], docList, { x: x, y: y, title: "droppedTable", width: 300, height: 100 });
- this.props.addDocument(newCol, false);
+ this.props.addDocument(newCol);
}
}
@action
@@ -202,7 +202,7 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
}
}
- setPreviewCursor = (x: number, y: number, drag: boolean) => {
+ setPreviewCursor = action((x: number, y: number, drag: boolean) => {
if (drag) {
this._downX = this._lastX = x;
this._downY = this._lastY = y;
@@ -217,7 +217,7 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
this._downY = y;
PreviewCursor.Show(x, y, this.onKeyPress, this.props.addLiveTextDocument, this.props.getTransform, this.props.addDocument);
}
- }
+ });
@action
onClick = (e: React.MouseEvent): void => {
@@ -296,7 +296,7 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
let palette = Array.from(Cast(this.props.container.props.Document.colorPalette, listSpec("string")) as string[]);
let usedPaletted = new Map<string, number>();
[...this.props.activeDocuments(), this.props.container.props.Document].map(child => {
- let bg = StrCast(child.layout instanceof Doc ? child.layout.backgroundColor : child.backgroundColor);
+ let bg = StrCast(Doc.Layout(child).backgroundColor);
if (palette.indexOf(bg) !== -1) {
palette.splice(palette.indexOf(bg), 1);
if (usedPaletted.get(bg)) usedPaletted.set(bg, usedPaletted.get(bg)! + 1);
@@ -350,7 +350,7 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
}
}
else {
- this.props.addDocument(newCollection, false);
+ this.props.addDocument(newCollection);
this.props.selectDocuments([newCollection]);
}
this.cleanupInteractions(false);
@@ -394,20 +394,22 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
let selRect = this.Bounds;
let selection: Doc[] = [];
this.props.activeDocuments().filter(doc => !doc.isBackground && doc.z === undefined).map(doc => {
+ let layoutDoc = Doc.Layout(doc);
var x = NumCast(doc.x);
var y = NumCast(doc.y);
- var w = NumCast(doc.width);
- var h = NumCast(doc.height);
+ var w = NumCast(layoutDoc.width);
+ var h = NumCast(layoutDoc.height);
if (this.intersectRect({ left: x, top: y, width: w, height: h }, selRect)) {
selection.push(doc);
}
});
if (!selection.length && selectBackgrounds) {
this.props.activeDocuments().filter(doc => doc.z === undefined).map(doc => {
+ let layoutDoc = Doc.Layout(doc);
var x = NumCast(doc.x);
var y = NumCast(doc.y);
- var w = NumCast(doc.width);
- var h = NumCast(doc.height);
+ var w = NumCast(layoutDoc.width);
+ var h = NumCast(layoutDoc.height);
if (this.intersectRect({ left: x, top: y, width: w, height: h }, selRect)) {
selection.push(doc);
}
@@ -420,10 +422,11 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
let size = this.props.getContainerTransform().transformDirection(this._lastX - this._downX, this._lastY - this._downY);
let otherBounds = { left: topLeft[0], top: topLeft[1], width: Math.abs(size[0]), height: Math.abs(size[1]) };
this.props.activeDocuments().filter(doc => doc.z !== undefined).map(doc => {
+ let layoutDoc = Doc.Layout(doc);
var x = NumCast(doc.x);
var y = NumCast(doc.y);
- var w = NumCast(doc.width);
- var h = NumCast(doc.height);
+ var w = NumCast(layoutDoc.width);
+ var h = NumCast(layoutDoc.height);
if (this.intersectRect({ left: x, top: y, width: w, height: h }, otherBounds)) {
selection.push(doc);
}