aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/collectionFreeForm
diff options
context:
space:
mode:
authorMonika <monika_hedman@brown.edu>2019-06-21 11:37:28 -0400
committerMonika <monika_hedman@brown.edu>2019-06-21 11:37:28 -0400
commit7eb3e346c6fddc23794f3dd0c33e280c4ee7bc24 (patch)
treed6e9ecd9d02aabd5324586c027ec769b750e0b6e /src/client/views/collections/collectionFreeForm
parent4b8a6b7a76ccadfd39ec037e282018c7d588dea8 (diff)
parent179afa6e80631fcb8899408c3961bf1757e5b19b (diff)
pulled from master
Diffstat (limited to 'src/client/views/collections/collectionFreeForm')
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss1
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx95
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx68
3 files changed, 103 insertions, 61 deletions
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
index e10ba9d7e..5ac2e1f9c 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
@@ -57,6 +57,7 @@
}
>.jsx-parser {
+ position:absolute;
z-index:0;
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index f382a10db..f756fe625 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,6 +1,6 @@
import { action, computed } from "mobx";
import { observer } from "mobx-react";
-import { Doc, HeightSym, WidthSym } from "../../../../new_fields/Doc";
+import { Doc, HeightSym, WidthSym, DocListCastAsync } from "../../../../new_fields/Doc";
import { Id } from "../../../../new_fields/FieldSymbols";
import { InkField, StrokeData } from "../../../../new_fields/InkField";
import { createSchema, makeInterface } from "../../../../new_fields/Schema";
@@ -25,6 +25,8 @@ import "./CollectionFreeFormView.scss";
import { MarqueeView } from "./MarqueeView";
import React = require("react");
import v5 = require("uuid/v5");
+import PDFMenu from "../../pdf/PDFMenu";
+import { ContextMenu } from "../../ContextMenu";
export const panZoomSchema = createSchema({
panX: "number",
@@ -80,30 +82,45 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
@undoBatch
@action
drop = (e: Event, de: DragManager.DropEvent) => {
- if (super.drop(e, de) && de.data instanceof DragManager.DocumentDragData) {
- if (de.data.droppedDocuments.length) {
- let dragDoc = de.data.droppedDocuments[0];
- let zoom = NumCast(dragDoc.zoomBasis, 1);
- let [xp, yp] = this.getTransform().transformPoint(de.x, de.y);
- let x = xp - de.data.xOffset / zoom;
- let y = yp - de.data.yOffset / zoom;
- let dropX = NumCast(de.data.droppedDocuments[0].x);
- let dropY = NumCast(de.data.droppedDocuments[0].y);
- de.data.droppedDocuments.forEach(d => {
- d.x = x + NumCast(d.x) - dropX;
- d.y = y + NumCast(d.y) - dropY;
- if (!NumCast(d.width)) {
- d.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;
- }
- this.bringToFront(d);
- });
+ if (super.drop(e, de)) {
+ if (de.data instanceof DragManager.DocumentDragData) {
+ if (de.data.droppedDocuments.length) {
+ let dragDoc = de.data.droppedDocuments[0];
+ let zoom = NumCast(dragDoc.zoomBasis, 1);
+ let [xp, yp] = this.getTransform().transformPoint(de.x, de.y);
+ let x = xp - de.data.xOffset / zoom;
+ let y = yp - de.data.yOffset / zoom;
+ let dropX = NumCast(de.data.droppedDocuments[0].x);
+ let dropY = NumCast(de.data.droppedDocuments[0].y);
+ de.data.droppedDocuments.forEach(d => {
+ d.x = x + NumCast(d.x) - dropX;
+ d.y = y + NumCast(d.y) - dropY;
+ if (!NumCast(d.width)) {
+ d.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;
+ }
+ this.bringToFront(d);
+ });
+ }
+ }
+ else if (de.data instanceof DragManager.AnnotationDragData) {
+ if (de.data.dropDocument) {
+ let dragDoc = de.data.dropDocument;
+ let zoom = NumCast(dragDoc.zoomBasis, 1);
+ let [xp, yp] = this.getTransform().transformPoint(de.x, de.y);
+ let x = xp - de.data.xOffset / zoom;
+ let y = yp - de.data.yOffset / zoom;
+ let dropX = NumCast(de.data.dropDocument.x);
+ let dropY = NumCast(de.data.dropDocument.y);
+ dragDoc.x = x + NumCast(dragDoc.x) - dropX;
+ dragDoc.y = y + NumCast(dragDoc.y) - dropY;
+ this.bringToFront(dragDoc);
+ }
}
- return true;
}
return false;
}
@@ -133,6 +150,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
let docs = this.childDocs || [];
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) / NumCast(docs[0].zoomBasis, 1) + minx : minx;
let miny = docs.length ? NumCast(docs[0].y) : 0;
@@ -322,6 +340,33 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
super.setCursorPosition(this.getTransform().transformPoint(e.clientX, e.clientY));
}
+ onContextMenu = () => {
+ ContextMenu.Instance.addItem({
+ description: "Arrange contents in grid",
+ event: async () => {
+ const docs = await DocListCastAsync(this.Document[this.props.fieldKey]);
+ if (docs) {
+ let startX = this.Document.panX || 0;
+ let x = startX;
+ let y = this.Document.panY || 0;
+ let i = 0;
+ const width = Math.max(...docs.map(doc => NumCast(doc.width)));
+ const height = Math.max(...docs.map(doc => NumCast(doc.height)));
+ for (const doc of docs) {
+ doc.x = x;
+ doc.y = y;
+ x += width + 20;
+ if (++i === 6) {
+ i = 0;
+ x = startX;
+ y += height + 20;
+ }
+ }
+ }
+ }
+ });
+ }
+
private childViews = () => [
<CollectionFreeFormBackgroundView key="backgroundView" {...this.props} {...this.getDocumentViewProps(this.props.Document)} />,
...this.views
@@ -332,7 +377,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
return (
<div className={containerName} ref={this.createDropTarget} onWheel={this.onPointerWheel}
style={{ borderRadius: "inherit" }}
- onPointerDown={this.onPointerDown} onPointerMove={this.onCursorMove} onDrop={this.onDrop.bind(this)} onDragOver={this.onDragOver} >
+ onPointerDown={this.onPointerDown} onPointerMove={this.onCursorMove} onDrop={this.onDrop.bind(this)} onDragOver={this.onDragOver} onContextMenu={this.onContextMenu}>
<MarqueeView container={this} activeDocuments={this.getActiveDocuments} selectDocuments={this.selectDocuments} isSelected={this.props.isSelected}
addDocument={this.addDocument} removeDocument={this.props.removeDocument} addLiveTextDocument={this.addLiveTextBox}
getContainerTransform={this.getContainerTransform} getTransform={this.getTransform}>
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index b93b90c72..ee7a9f64f 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -45,12 +45,14 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
_commandExecuted = false;
@action
- cleanupInteractions = (all: boolean = false) => {
+ cleanupInteractions = (all: boolean = false, rem_keydown: boolean = true) => {
if (all) {
document.removeEventListener("pointerup", this.onPointerUp, true);
document.removeEventListener("pointermove", this.onPointerMove, true);
}
- document.removeEventListener("keydown", this.marqueeCommand, true);
+ if (all) {
+ document.removeEventListener("keydown", this.marqueeCommand, true);
+ }
this._visible = false;
}
@@ -93,7 +95,8 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
}
});
} else if (!e.ctrlKey) {
- let newBox = Docs.TextDocument({ width: 200, height: 100, x: x, y: y, title: "-typed text-" });
+ let newBox = Docs.TextDocument({ width: 200, height: 30, x: x, y: y, title: "-typed text-" });
+ newBox.proto!.autoHeight = true;
this.props.addLiveTextDocument(newBox);
}
e.stopPropagation();
@@ -145,6 +148,7 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
this._downY = this._lastY = e.pageY;
this._commandExecuted = false;
PreviewCursor.Visible = false;
+ this.cleanupInteractions(true);
if (e.button === 2 || (e.button === 0 && e.altKey)) {
if (!this.props.container.props.active()) this.props.selectDocuments([this.props.container.props.Document]);
document.addEventListener("pointermove", this.onPointerMove, true);
@@ -180,14 +184,21 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
@action
onPointerUp = (e: PointerEvent): void => {
+ console.log("pointer up!");
if (this._visible) {
+ console.log("visible");
let mselect = this.marqueeSelect();
if (!e.shiftKey) {
SelectionManager.DeselectAll(mselect.length ? undefined : this.props.container.props.Document);
}
this.props.selectDocuments(mselect.length ? mselect : [this.props.container.props.Document]);
+ mselect.length ? this.cleanupInteractions(true, false) : this.cleanupInteractions(true);
}
- this.cleanupInteractions(true);
+ else {
+ console.log("invisible");
+ this.cleanupInteractions(true);
+ }
+
if (e.altKey) {
e.preventDefault();
}
@@ -264,13 +275,11 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
panY: 0,
borderRounding: e.key === "e" ? -1 : undefined,
backgroundColor: this.props.container.isAnnotationOverlay ? undefined : "white",
- scale: zoomBasis,
- width: bounds.width * zoomBasis,
- height: bounds.height * zoomBasis,
+ width: bounds.width,
+ height: bounds.height,
ink: inkData ? new InkField(this.marqueeInkSelect(inkData)) : undefined,
title: e.key === "s" || e.key === "S" ? "-summary-" : e.key === "p" ? "-summary-" : "a nested collection",
});
- newCollection.zoomBasis = zoomBasis;
this.marqueeInkDelete(inkData);
if (e.key === "s") {
@@ -293,35 +302,22 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
this.props.addLiveTextDocument(container);
// });
} else if (e.key === "S") {
- await htmlToImage.toPng(this._mainCont.current!, { width: bounds.width * zoomBasis, height: bounds.height * zoomBasis, quality: 0.2 }).then((dataUrl) => {
- selected.map(d => {
- this.props.removeDocument(d);
- d.x = NumCast(d.x) - bounds.left - bounds.width / 2;
- d.y = NumCast(d.y) - bounds.top - bounds.height / 2;
- d.page = -1;
- return d;
- });
- let summary = Docs.TextDocument({ x: bounds.left, y: bounds.top, width: 300, height: 100, backgroundColor: "#e2ad32" /* yellow */, title: "-summary-" });
- SearchBox.convertDataUri(dataUrl, "icon" + summary[Id] + "_image").then((returnedFilename) => {
- if (returnedFilename) {
- let url = DocServer.prepend(returnedFilename);
- let imageSummary = Docs.ImageDocument(url, {
- x: bounds.left, y: bounds.top + 100 / zoomBasis,
- width: 150, height: bounds.height / bounds.width * 150, title: "-summary image-"
- });
- summary.imageSummary = imageSummary;
- this.props.addDocument(imageSummary, false);
- }
- });
- newCollection.proto!.summaryDoc = summary;
- selected = [newCollection];
- newCollection.x = bounds.left + bounds.width;
- //this.props.addDocument(newCollection, false);
- summary.proto!.summarizedDocs = new List<Doc>(selected);
- summary.proto!.maximizeLocation = "inTab"; // or "inPlace", or "onRight"
-
- this.props.addLiveTextDocument(summary);
+ selected.map(d => {
+ this.props.removeDocument(d);
+ d.x = NumCast(d.x) - bounds.left - bounds.width / 2;
+ d.y = NumCast(d.y) - bounds.top - bounds.height / 2;
+ d.page = -1;
+ return d;
});
+ let summary = Docs.TextDocument({ x: bounds.left, y: bounds.top, width: 300, height: 100, backgroundColor: "#e2ad32" /* yellow */, title: "-summary-" });
+ newCollection.proto!.summaryDoc = summary;
+ selected = [newCollection];
+ newCollection.x = bounds.left + bounds.width;
+ //this.props.addDocument(newCollection, false);
+ summary.proto!.summarizedDocs = new List<Doc>(selected);
+ summary.proto!.maximizeLocation = "inTab"; // or "inPlace", or "onRight"
+
+ this.props.addLiveTextDocument(summary);
}
else {
this.props.addDocument(newCollection, false);