aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbob <bcz@cs.brown.edu>2019-02-22 15:25:00 -0500
committerbob <bcz@cs.brown.edu>2019-02-22 15:25:00 -0500
commit9a43ea5aefd7b1153f4d865aac0d6c541c989981 (patch)
tree3a2994e6c74657f168e9d9d8cf76ab98c45024c1 /src
parent85d7a3d9aee44f0b199dddace92f7a683bc33eb6 (diff)
parent1e83695f1380b7824d36bdc55305c44117f6da2c (diff)
Merge branch 'collectionView'
Diffstat (limited to 'src')
-rw-r--r--src/client/Server.ts2
-rw-r--r--src/client/documents/Documents.ts2
-rw-r--r--src/client/util/DragManager.ts1
-rw-r--r--src/client/views/DocumentDecorations.tsx2
-rw-r--r--src/client/views/Main.tsx3
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx6
-rw-r--r--src/client/views/collections/CollectionFreeFormView.tsx62
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx16
-rw-r--r--src/client/views/collections/CollectionView.tsx20
-rw-r--r--src/client/views/collections/CollectionViewBase.tsx82
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx24
-rw-r--r--src/client/views/nodes/DocumentView.tsx3
12 files changed, 129 insertions, 94 deletions
diff --git a/src/client/Server.ts b/src/client/Server.ts
index 06ac22c61..2d162b93a 100644
--- a/src/client/Server.ts
+++ b/src/client/Server.ts
@@ -34,7 +34,7 @@ export class Server {
}
}));
} else if (cached != FieldWaiting) {
- callback(cached);
+ setTimeout(() => callback(cached as Field), 0);
} else {
reaction(() => {
return this.ClientFieldsCached.get(fieldid);
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index bfa6cb7a9..156a09316 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -13,7 +13,7 @@ import { CollectionFreeFormView } from "../views/collections/CollectionFreeFormV
import { FieldId } from "../../fields/Field";
import { CollectionView, CollectionViewType } from "../views/collections/CollectionView";
-interface DocumentOptions {
+export interface DocumentOptions {
x?: number;
y?: number;
width?: number;
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 6d5fe12a7..eb4b3aeaa 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -44,6 +44,7 @@ export namespace DragManager {
drop: (e: Event, de: DropEvent) => void;
}
+
export function MakeDropTarget(element: HTMLElement, options: DropOptions): DragDropDisposer {
if ("canDrop" in element.dataset) {
throw new Error("Element is already droppable, can't make it droppable again");
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 395a37ba5..7b64a4c2c 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -28,7 +28,7 @@ export class DocumentDecorations extends React.Component {
}
let transform = (element.props.ScreenToLocalTransform().scale(element.props.Scaling)).inverse();
var [sptX, sptY] = transform.transformPoint(0, 0);
- let [bptX, bptY] = transform.transformPoint(element.props.PanelSize[0], element.props.PanelSize[1]);
+ let [bptX, bptY] = transform.transformPoint(element.props.PanelWidth, element.props.PanelHeight);
return {
x: Math.min(sptX, bounds.x), y: Math.min(sptY, bounds.y),
r: Math.max(bptX, bounds.r), b: Math.max(bptY, bounds.b)
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index fe1a999ec..6f6a89839 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -107,7 +107,8 @@ Documents.initProtos(() => {
<DocumentView Document={mainContainer}
AddDocument={undefined} RemoveDocument={undefined} ScreenToLocalTransform={() => Transform.Identity}
Scaling={1}
- PanelSize={[0, 0]}
+ PanelWidth={0}
+ PanelHeight={0}
isTopMost={true}
ContainingCollectionView={undefined} />
<DocumentDecorations />
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 752007439..7ac8ea5e4 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -14,8 +14,9 @@ import { DragManager } from "../../util/DragManager";
import { undoBatch } from "../../util/UndoManager";
import { DocumentView } from "../nodes/DocumentView";
import "./CollectionDockingView.scss";
-import { CollectionViewProps, COLLECTION_BORDER_WIDTH, SubCollectionViewProps } from "./CollectionView";
+import { COLLECTION_BORDER_WIDTH } from "./CollectionView";
import React = require("react");
+import { SubCollectionViewProps } from "./CollectionViewBase";
@observer
export class CollectionDockingView extends React.Component<SubCollectionViewProps> {
@@ -289,7 +290,8 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
AddDocument={undefined}
RemoveDocument={undefined}
Scaling={this._parentScaling}
- PanelSize={[this._nativeWidth, this._nativeHeight]}
+ PanelWidth={this._nativeWidth}
+ PanelHeight={this._nativeHeight}
ScreenToLocalTransform={this.ScreenToLocalTransform}
isTopMost={true}
ContainingCollectionView={undefined} />
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index b78b1a3b6..e31fb25b9 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -4,20 +4,18 @@ import { action, computed, trace } from "mobx";
import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
import { DragManager } from "../../util/DragManager";
import "./CollectionFreeFormView.scss";
-import { COLLECTION_BORDER_WIDTH, CollectionViewProps, SubCollectionViewProps } from "./CollectionView";
+import { COLLECTION_BORDER_WIDTH } from "./CollectionView";
import { KeyStore } from "../../../fields/KeyStore";
import { Document } from "../../../fields/Document";
import { ListField } from "../../../fields/ListField";
-import { NumberField } from "../../../fields/NumberField";
-import { Documents } from "../../documents/Documents";
import { FieldWaiting } from "../../../fields/Field";
import { Transform } from "../../util/Transform";
import { DocumentView } from "../nodes/DocumentView";
import { undoBatch } from "../../util/UndoManager";
-import { jSXElement } from "babel-types";
+import { CollectionViewBase, SubCollectionViewProps } from "./CollectionViewBase";
@observer
-export class CollectionFreeFormView extends React.Component<SubCollectionViewProps> {
+export class CollectionFreeFormView extends CollectionViewBase {
private _canvasRef = React.createRef<HTMLDivElement>();
private _lastX: number = 0;
private _lastY: number = 0;
@@ -45,13 +43,8 @@ export class CollectionFreeFormView extends React.Component<SubCollectionViewPro
@undoBatch
@action
drop = (e: Event, de: DragManager.DropEvent) => {
+ super.drop(e, de);
const doc: DocumentView = de.data["document"];
- if (doc.props.ContainingCollectionView && doc.props.ContainingCollectionView !== this.props.CollectionView) {
- if (doc.props.RemoveDocument) {
- doc.props.RemoveDocument(doc.props.Document);
- }
- this.props.addDocument(doc.props.Document);
- }
const xOffset = de.data["xOffset"] as number || 0;
const yOffset = de.data["yOffset"] as number || 0;
//this should be able to use translate and scale methods on an Identity transform, no?
@@ -62,21 +55,6 @@ export class CollectionFreeFormView extends React.Component<SubCollectionViewPro
doc.props.Document.SetNumber(KeyStore.X, x);
doc.props.Document.SetNumber(KeyStore.Y, y);
this.bringToFront(doc);
- e.stopPropagation();
- }
-
- private dropDisposer?: DragManager.DragDropDisposer;
- createDropTarget = (ele: HTMLDivElement) => {
- if (this.dropDisposer) {
- this.dropDisposer();
- }
- if (ele) {
- this.dropDisposer = DragManager.MakeDropTarget(ele, {
- handlers: {
- drop: this.drop
- }
- });
- }
}
@action
@@ -148,36 +126,11 @@ export class CollectionFreeFormView extends React.Component<SubCollectionViewPro
@action
onDrop = (e: React.DragEvent): void => {
- e.stopPropagation()
- e.preventDefault()
- let fReader = new FileReader()
- let file = e.dataTransfer.items[0].getAsFile();
- let that = this;
const panx: number = this.props.Document.GetNumber(KeyStore.PanX, 0);
const pany: number = this.props.Document.GetNumber(KeyStore.PanY, 0);
let x = e.pageX - panx
let y = e.pageY - pany
-
- fReader.addEventListener("load", action("drop", () => {
- if (fReader.result) {
- let url = "" + fReader.result;
- let doc = Documents.ImageDocument(url, {
- x: x, y: y
- })
- let docs = that.props.Document.GetT(KeyStore.Data, ListField);
- if (docs != FieldWaiting) {
- if (!docs) {
- docs = new ListField<Document>();
- that.props.Document.Set(KeyStore.Data, docs)
- }
- docs.Data.push(doc);
- }
- }
- }), false)
-
- if (file) {
- fReader.readAsDataURL(file)
- }
+ super.onDrop(e, { x: x, y: y });
}
onDragOver = (): void => {
@@ -234,7 +187,8 @@ export class CollectionFreeFormView extends React.Component<SubCollectionViewPro
ScreenToLocalTransform={this.getTransform}
isTopMost={false}
Scaling={1}
- PanelSize={[doc.GetNumber(KeyStore.Width, 0), doc.GetNumber(KeyStore.Height, 0)]}
+ PanelWidth={doc.GetNumber(KeyStore.Width, 0)}
+ PanelHeight={doc.GetNumber(KeyStore.Height, 0)}
ContainingCollectionView={this.props.CollectionView} />);
})
}
@@ -249,7 +203,7 @@ export class CollectionFreeFormView extends React.Component<SubCollectionViewPro
onPointerDown={this.onPointerDown}
onWheel={this.onPointerWheel}
onContextMenu={(e) => e.preventDefault()}
- onDrop={this.onDrop}
+ onDrop={this.onDrop.bind(this)}
onDragOver={this.onDragOver}
style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px`, }}
ref={this.createDropTarget}>
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index f25e721c0..7e7d23fe4 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -5,7 +5,7 @@ import Measure from "react-measure";
import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults } from "react-table";
import "react-table/react-table.css";
import { Document } from "../../../fields/Document";
-import { Field } from "../../../fields/Field";
+import { Field, FieldWaiting } from "../../../fields/Field";
import { KeyStore } from "../../../fields/KeyStore";
import { CompileScript, ToField } from "../../util/Scripting";
import { Transform } from "../../util/Transform";
@@ -13,10 +13,11 @@ import { EditableView } from "../EditableView";
import { DocumentView } from "../nodes/DocumentView";
import { FieldView, FieldViewProps } from "../nodes/FieldView";
import "./CollectionSchemaView.scss";
-import { COLLECTION_BORDER_WIDTH, CollectionViewProps, SubCollectionViewProps } from "./CollectionView";
+import { COLLECTION_BORDER_WIDTH } from "./CollectionView";
+import { CollectionViewBase } from "./CollectionViewBase";
@observer
-export class CollectionSchemaView extends React.Component<SubCollectionViewProps> {
+export class CollectionSchemaView extends CollectionViewBase {
private _mainCont = React.createRef<HTMLDivElement>();
private DIVIDER_WIDTH = 5;
@@ -117,6 +118,7 @@ export class CollectionSchemaView extends React.Component<SubCollectionViewProps
}
}
+
getTransform = (): Transform => {
return this.props.ScreenToLocalTransform().translate(- COLLECTION_BORDER_WIDTH - this.DIVIDER_WIDTH - this._dividerX, - COLLECTION_BORDER_WIDTH).scale(1 / this._parentScaling);
}
@@ -147,7 +149,8 @@ export class CollectionSchemaView extends React.Component<SubCollectionViewProps
ScreenToLocalTransform={this.getTransform}
Scaling={this._parentScaling}
isTopMost={false}
- PanelSize={[this._panelWidth, this._panelHeight]}
+ PanelWidth={this._panelWidth}
+ PanelHeight={this._panelHeight}
ContainingCollectionView={this.props.CollectionView} />
</div>
}
@@ -181,7 +184,10 @@ export class CollectionSchemaView extends React.Component<SubCollectionViewProps
}
</Measure>
<div className="collectionSchemaView-dividerDragger" style={{ position: "relative", background: "black", float: "left", width: `${this.DIVIDER_WIDTH}px`, height: "100%" }} onPointerDown={this.onDividerDown} />
- <div className="collectionSchemaView-previewRegion" style={{ position: "relative", float: "left", width: `calc(${100 - this._splitPercentage}% - ${this.DIVIDER_WIDTH}px)`, height: "100%" }}>
+ <div className="collectionSchemaView-previewRegion"
+ onDrop={(e: React.DragEvent) => this.onDrop(e, {})}
+ ref={this.createDropTarget}
+ style={{ position: "relative", float: "left", width: `calc(${100 - this._splitPercentage}% - ${this.DIVIDER_WIDTH}px)`, height: "100%" }}>
{content}
</div>
</div >
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 651d85879..ff1803ec3 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -1,36 +1,18 @@
import { action, computed } from "mobx";
import { observer } from "mobx-react";
import { Document } from "../../../fields/Document";
-import { Key } from "../../../fields/Key";
import { ListField } from "../../../fields/ListField";
import { SelectionManager } from "../../util/SelectionManager";
import { ContextMenu } from "../ContextMenu";
import React = require("react");
-import { Transform } from "../../util/Transform";
import { KeyStore } from "../../../fields/KeyStore";
import { NumberField } from "../../../fields/NumberField";
import { CollectionFreeFormView } from "./CollectionFreeFormView";
import { CollectionDockingView } from "./CollectionDockingView";
import { CollectionSchemaView } from "./CollectionSchemaView";
-import { Opt } from "../../../fields/Field";
+import { CollectionViewProps } from "./CollectionViewBase";
-export interface CollectionViewProps {
- fieldKey: Key;
- Document: Document;
- ScreenToLocalTransform: () => Transform;
- isSelected: () => boolean;
- isTopMost: boolean;
- select: (ctrlPressed: boolean) => void;
- BackgroundView?: () => JSX.Element;
-}
-
-export interface SubCollectionViewProps extends CollectionViewProps {
- active: () => boolean;
- addDocument: (doc: Document) => void;
- removeDocument: (doc: Document) => boolean;
- CollectionView: Opt<CollectionView>;
-}
export enum CollectionViewType {
Invalid,
diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx
new file mode 100644
index 000000000..06de56383
--- /dev/null
+++ b/src/client/views/collections/CollectionViewBase.tsx
@@ -0,0 +1,82 @@
+import { action, computed } from "mobx";
+import { Document } from "../../../fields/Document";
+import { ListField } from "../../../fields/ListField";
+import React = require("react");
+import { KeyStore } from "../../../fields/KeyStore";
+import { Opt, FieldWaiting } from "../../../fields/Field";
+import { undoBatch } from "../../util/UndoManager";
+import { DragManager } from "../../util/DragManager";
+import { DocumentView } from "../nodes/DocumentView";
+import { Documents, DocumentOptions } from "../../documents/Documents";
+import { Key } from "../../../fields/Key";
+import { Transform } from "../../util/Transform";
+
+
+export interface CollectionViewProps {
+ fieldKey: Key;
+ Document: Document;
+ ScreenToLocalTransform: () => Transform;
+ isSelected: () => boolean;
+ isTopMost: boolean;
+ select: (ctrlPressed: boolean) => void;
+ BackgroundView?: () => JSX.Element;
+}
+export interface SubCollectionViewProps extends CollectionViewProps {
+ active: () => boolean;
+ addDocument: (doc: Document) => void;
+ removeDocument: (doc: Document) => boolean;
+ CollectionView: any;
+}
+
+export class CollectionViewBase extends React.Component<SubCollectionViewProps> {
+ private dropDisposer?: DragManager.DragDropDisposer;
+ protected createDropTarget = (ele: HTMLDivElement) => {
+ if (this.dropDisposer) {
+ this.dropDisposer();
+ }
+ if (ele) {
+ this.dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.drop.bind(this) } });
+ }
+ }
+
+ @undoBatch
+ @action
+ protected drop(e: Event, de: DragManager.DropEvent) {
+ const doc: DocumentView = de.data["document"];
+ if (doc.props.ContainingCollectionView && doc.props.ContainingCollectionView !== this.props.CollectionView) {
+ if (doc.props.RemoveDocument) {
+ doc.props.RemoveDocument(doc.props.Document);
+ }
+ this.props.addDocument(doc.props.Document);
+ }
+ e.stopPropagation();
+ }
+
+ @action
+ protected onDrop(e: React.DragEvent, options: DocumentOptions): void {
+ e.stopPropagation()
+ e.preventDefault()
+ let fReader = new FileReader()
+ let file = e.dataTransfer.items[0].getAsFile();
+ let that = this;
+
+ fReader.addEventListener("load", action("drop", () => {
+ if (fReader.result) {
+ let url = "" + fReader.result;
+ let doc = Documents.ImageDocument(url, options)
+ let docs = that.props.Document.GetT(KeyStore.Data, ListField);
+ if (docs != FieldWaiting) {
+ if (!docs) {
+ docs = new ListField<Document>();
+ that.props.Document.Set(KeyStore.Data, docs)
+ }
+ docs.Data.push(doc);
+ }
+ }
+ }), false)
+
+ if (file) {
+ fReader.readAsDataURL(file)
+ }
+ }
+}
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 5568935fa..ad6756918 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -1,4 +1,4 @@
-import { computed } from "mobx";
+import { computed, trace } from "mobx";
import { observer } from "mobx-react";
import { KeyStore } from "../../../fields/KeyStore";
import { NumberField } from "../../../fields/NumberField";
@@ -69,15 +69,25 @@ export class CollectionFreeFormDocumentView extends React.Component<DocumentView
this.props.Document.SetData(KeyStore.ZIndex, h, NumberField)
}
+ @computed
+ get parentScaling() {
+ return this.nativeWidth > 0 ? this.width / this.nativeWidth : 1;
+ }
getTransform = (): Transform => {
- var parentScaling = this.nativeWidth > 0 ? this.width / this.nativeWidth : 1;
return this.props.ScreenToLocalTransform().
- translate(-this.props.Document.GetNumber(KeyStore.X, 0), -this.props.Document.GetNumber(KeyStore.Y, 0)).scale(1 / parentScaling);
+ translate(-this.props.Document.GetNumber(KeyStore.X, 0), -this.props.Document.GetNumber(KeyStore.Y, 0)).scale(1 / this.parentScaling);
+ }
+
+ @computed
+ get docView() {
+ return <DocumentView {...this.props}
+ Scaling={this.parentScaling}
+ ScreenToLocalTransform={this.getTransform}
+ />
}
render() {
- var parentScaling = this.nativeWidth > 0 ? this.width / this.nativeWidth : 1;
return (
<div ref={this._mainCont} style={{
transformOrigin: "left top",
@@ -88,11 +98,7 @@ export class CollectionFreeFormDocumentView extends React.Component<DocumentView
zIndex: this.zIndex,
backgroundColor: "transparent"
}} >
-
- <DocumentView {...this.props}
- Scaling={parentScaling}
- ScreenToLocalTransform={this.getTransform}
- />
+ {this.docView}
</div>
);
}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 69e413c6f..c026e13cd 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -31,7 +31,8 @@ export interface DocumentViewProps {
isTopMost: boolean;
//tfs: This shouldn't be necessary I don't think
Scaling: number;
- PanelSize: number[];
+ PanelWidth: number;
+ PanelHeight: number;
}
export interface JsxArgs extends DocumentViewProps {
Keys: { [name: string]: Key }