aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Main.tsx8
-rw-r--r--src/documents/Documents.ts21
-rw-r--r--src/fields/Key.ts2
-rw-r--r--src/views/freeformcanvas/CollectionFreeFormView.scss15
-rw-r--r--src/views/freeformcanvas/CollectionFreeFormView.tsx83
-rw-r--r--src/views/freeformcanvas/FreeFormCanvas.tsx23
-rw-r--r--src/views/freeformcanvas/NodeContainer.tsx28
-rw-r--r--src/views/nodes/DocumentView.tsx4
-rw-r--r--src/views/nodes/FieldTextBox.tsx20
9 files changed, 162 insertions, 42 deletions
diff --git a/src/Main.tsx b/src/Main.tsx
index 583761dbd..a3b9bc96f 100644
--- a/src/Main.tsx
+++ b/src/Main.tsx
@@ -2,17 +2,14 @@ import * as React from 'react';
import * as ReactDOM from 'react-dom';
import "./Main.scss";
import { NodeCollectionStore } from './stores/NodeCollectionStore';
-import { RootStore } from './stores/RootStore';
import { StaticTextNodeStore } from './stores/StaticTextNodeStore';
import { VideoNodeStore } from './stores/VideoNodeStore';
import { FreeFormCanvas } from './views/freeformcanvas/FreeFormCanvas';
import { Key, KeyStore as KS } from './fields/Key';
import { NumberField } from './fields/NumberField';
import { Document } from './fields/Document';
-import { TextField } from './fields/TextField';
import { configure, runInAction } from 'mobx';
import { NodeStore } from './stores/NodeStore';
-import { ListField } from './fields/ListField';
import { Documents } from './documents/Documents';
configure({
@@ -48,9 +45,14 @@ runInAction(() => {
doc2.SetField(KS.X, new NumberField(150));
doc2.SetField(KS.Y, new NumberField(20));
let doc3 = Documents.ImageDocument("https://static.boredpanda.com/blog/wp-content/uploads/2018/04/5acb63d83493f__700-png.jpg", {
+ x: 150, y: 500
+ });
+ let docset = new Array<Document>(doc1, doc2);
+ let doc4 = Documents.CollectionDocument(docset, {
x: 100, y: 400
});
mainNodeCollection.Docs.push(doc1);
mainNodeCollection.Docs.push(doc2);
+ mainNodeCollection.Docs.push(doc4);
mainNodeCollection.Docs.push(doc3);
}); \ No newline at end of file
diff --git a/src/documents/Documents.ts b/src/documents/Documents.ts
index 20d4596fd..bba678bbd 100644
--- a/src/documents/Documents.ts
+++ b/src/documents/Documents.ts
@@ -68,4 +68,25 @@ export namespace Documents {
doc.SetField(KeyStore.Data, new TextField(url));
return doc;
}
+
+ let collectionProto:Document;
+ function GetCollectionPrototype(): Document {
+ if(!collectionProto) {
+ collectionProto = new Document();
+ collectionProto.SetField(KeyStore.X, new NumberField(150));
+ collectionProto.SetField(KeyStore.Y, new NumberField(0));
+ collectionProto.SetField(KeyStore.Width, new NumberField(300));
+ collectionProto.SetField(KeyStore.Height, new NumberField(300));
+ collectionProto.SetField(KeyStore.Layout, new TextField('<CollectionFreeFormView doc={doc} fieldKey={DataKey}/>'));
+ collectionProto.SetField(KeyStore.LayoutKeys, new ListField([KeyStore.Data]));
+ }
+ return collectionProto;
+ }
+
+ export function CollectionDocument( documents: Array<Document>, options:DocumentOptions = {}): Document {
+ let doc = GetCollectionPrototype().MakeDelegate();
+ setupOptions(doc, options);
+ doc.SetField(KeyStore.Data, new ListField(documents));
+ return doc;
+ }
} \ No newline at end of file
diff --git a/src/fields/Key.ts b/src/fields/Key.ts
index cd67e0a00..db30f545d 100644
--- a/src/fields/Key.ts
+++ b/src/fields/Key.ts
@@ -34,6 +34,8 @@ export namespace KeyStore {
export let Prototype = new Key("Prototype");
export let X = new Key("X");
export let Y = new Key("Y");
+ export let PanX = new Key("PanX");
+ export let PanY = new Key("PanY");
export let Width = new Key("Width");
export let Height = new Key("Height");
export let Data = new Key("Data");
diff --git a/src/views/freeformcanvas/CollectionFreeFormView.scss b/src/views/freeformcanvas/CollectionFreeFormView.scss
new file mode 100644
index 000000000..cb4805eb3
--- /dev/null
+++ b/src/views/freeformcanvas/CollectionFreeFormView.scss
@@ -0,0 +1,15 @@
+.collectionfreeformview-container {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+
+ .collectionfreeformview {
+ position: absolute;
+ top: 0;
+ left: 0;
+ }
+}
+
diff --git a/src/views/freeformcanvas/CollectionFreeFormView.tsx b/src/views/freeformcanvas/CollectionFreeFormView.tsx
new file mode 100644
index 000000000..7c523e70d
--- /dev/null
+++ b/src/views/freeformcanvas/CollectionFreeFormView.tsx
@@ -0,0 +1,83 @@
+import { observer } from "mobx-react";
+import { Key, KeyStore } from "../../fields/Key";
+import "./FreeFormCanvas.scss";
+import React = require("react");
+import { action } from "mobx";
+import { Document } from "../../fields/Document";
+import {DocumentViewModel} from "../../viewmodels/DocumentViewModel";
+import {DocumentView} from "../nodes/DocumentView";
+import {ListField} from "../../fields/ListField";
+import {NumberField} from "../../fields/NumberField";
+
+interface IProps {
+ fieldKey:Key;
+ doc:Document;
+}
+
+@observer
+export class CollectionFreeFormView extends React.Component<IProps> {
+
+ private _isPointerDown: boolean = false;
+
+ constructor(props:IProps) {
+ super(props);
+ }
+
+ @action
+ onPointerDown = (e: React.PointerEvent): void => {
+ e.stopPropagation();
+ this._isPointerDown = true;
+ document.removeEventListener("pointermove", this.onPointerMove);
+ document.addEventListener("pointermove", this.onPointerMove);
+ document.removeEventListener("pointerup", this.onPointerUp);
+ document.addEventListener("pointerup", this.onPointerUp);
+ }
+
+ @action
+ onPointerUp = (e: PointerEvent): void => {
+ e.stopPropagation();
+ this._isPointerDown = false;
+ document.removeEventListener("pointermove", this.onPointerMove);
+ document.removeEventListener("pointerup", this.onPointerUp);
+ }
+
+ @action
+ onPointerMove = (e: PointerEvent): void => {
+ e.preventDefault();
+ e.stopPropagation();
+ if (!this._isPointerDown) {
+ return;
+ }
+ const {doc} = this.props;
+ let x = doc.GetFieldValue(KeyStore.PanX, NumberField, Number(0));
+ let y = doc.GetFieldValue(KeyStore.PanY, NumberField, Number(0));
+ doc.SetFieldValue(KeyStore.PanX, x+e.movementX, NumberField);
+ doc.SetFieldValue(KeyStore.PanY, y+e.movementY, NumberField);
+ }
+
+ @action
+ onPointerWheel = (e: React.WheelEvent): void => {
+ e.stopPropagation();
+
+ let scaleAmount = 1 - (e.deltaY / 1000);
+ //this.props.store.Scale *= scaleAmount;
+ }
+
+ render() {
+ const {fieldKey, doc} = this.props;
+ const value: Document[] = doc.GetFieldValue(fieldKey, ListField, []);
+ const panx: number = doc.GetFieldValue(KeyStore.PanX, NumberField, Number(0));
+ const pany: number = doc.GetFieldValue(KeyStore.PanY, NumberField, Number(0));
+ return (
+ <div className="collectionfreeformview-container" onPointerDown={this.onPointerDown} onWheel={this.onPointerWheel}>
+ <div className="collectionfreeformview" style={{ transform: `translate(${panx}px, ${pany}px)`, transformOrigin: '50% 50%' }}>
+ <div className="node-container">
+ {value.map(doc => {
+ return (<DocumentView key={doc.Id} dvm={new DocumentViewModel(doc)} />);
+ })}
+ </div>
+ </div>
+ </div>
+ );
+ }
+} \ No newline at end of file
diff --git a/src/views/freeformcanvas/FreeFormCanvas.tsx b/src/views/freeformcanvas/FreeFormCanvas.tsx
index 344eb2bd8..cee093fcb 100644
--- a/src/views/freeformcanvas/FreeFormCanvas.tsx
+++ b/src/views/freeformcanvas/FreeFormCanvas.tsx
@@ -1,15 +1,18 @@
import { observer } from "mobx-react";
+import { Key } from "../../fields/Key";
import { NodeCollectionStore } from "../../stores/NodeCollectionStore";
import "./FreeFormCanvas.scss";
-import { NodeContainer } from "./NodeContainer";
import React = require("react");
-import { KeyStore } from "../../fields/Key";
-import { NumberField } from "../../fields/NumberField";
-import { TextField } from "../../fields/TextField";
import { action } from "mobx";
+import { Document } from "../../fields/Document";
+import {DocumentViewModel} from "../../viewmodels/DocumentViewModel";
+import {DocumentView} from "../nodes/DocumentView";
+import {TextField} from "../../fields/TextField";
+import {ListField} from "../../fields/ListField";
+import {Field} from "../../fields/Field";
interface IProps {
- store: NodeCollectionStore
+ store: NodeCollectionStore;
}
@observer
@@ -17,6 +20,10 @@ export class FreeFormCanvas extends React.Component<IProps> {
private _isPointerDown: boolean = false;
+ constructor(props:IProps) {
+ super(props);
+ }
+
@action
onPointerDown = (e: React.PointerEvent): void => {
e.stopPropagation();
@@ -63,7 +70,11 @@ export class FreeFormCanvas extends React.Component<IProps> {
return (
<div className="freeformcanvas-container" onPointerDown={this.onPointerDown} onWheel={this.onPointerWheel}>
<div className="freeformcanvas" style={{ transform: store.Transform, transformOrigin: '50% 50%' }}>
- <NodeContainer store={store} />
+ <div className="node-container">
+ {this.props.store.Docs.map(doc => {
+ return (<DocumentView key={doc.Id} dvm={new DocumentViewModel(doc)} />);
+ })}
+ </div>
</div>
</div>
);
diff --git a/src/views/freeformcanvas/NodeContainer.tsx b/src/views/freeformcanvas/NodeContainer.tsx
deleted file mode 100644
index 6c3cb2af2..000000000
--- a/src/views/freeformcanvas/NodeContainer.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import { observer } from "mobx-react";
-import { NodeCollectionStore } from "../../stores/NodeCollectionStore";
-import { StaticTextNodeStore } from "../../stores/StaticTextNodeStore";
-import { VideoNodeStore } from "../../stores/VideoNodeStore";
-import { TextNodeView } from "../nodes/TextNodeView";
-import { VideoNodeView } from "../nodes/VideoNodeView";
-import "./FreeFormCanvas.scss";
-import React = require("react");
-import { DocumentView } from "../nodes/DocumentView";
-import { DocumentViewModel } from "../../viewmodels/DocumentViewModel";
-
-interface IProps {
- store: NodeCollectionStore
-}
-
-@observer
-export class NodeContainer extends React.Component<IProps> {
-
- render() {
- return (
- <div className="node-container">
- {this.props.store.Docs.map(doc => {
- return (<DocumentView key={doc.Id} dvm={new DocumentViewModel(doc)} />);
- })}
- </div>
- );
- }
-} \ No newline at end of file
diff --git a/src/views/nodes/DocumentView.tsx b/src/views/nodes/DocumentView.tsx
index f31069aa3..b9fbef91c 100644
--- a/src/views/nodes/DocumentView.tsx
+++ b/src/views/nodes/DocumentView.tsx
@@ -7,6 +7,8 @@ import { TextField } from "../../fields/TextField";
import { DocumentViewModel } from "../../viewmodels/DocumentViewModel";
import { ListField } from "../../fields/ListField";
import { FieldTextBox } from "../nodes/FieldTextBox"
+import { FreeFormCanvas } from "../freeformcanvas/FreeFormCanvas"
+import { CollectionFreeFormView } from "../freeformcanvas/CollectionFreeFormView"
import "./NodeView.scss"
const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this?
@@ -83,7 +85,7 @@ export class DocumentView extends React.Component<IProps> {
height: this.height
}}>
<JsxParser
- components={{ FieldTextBox }}
+ components={{ FieldTextBox, FreeFormCanvas, CollectionFreeFormView }}
bindings={bindings}
jsx={this.layout}
/>
diff --git a/src/views/nodes/FieldTextBox.tsx b/src/views/nodes/FieldTextBox.tsx
index 4615940bd..5df3e6012 100644
--- a/src/views/nodes/FieldTextBox.tsx
+++ b/src/views/nodes/FieldTextBox.tsx
@@ -11,15 +11,27 @@ interface IProps {
test:string;
}
+// FieldTextBox: Displays an editable plain text node that maps to a specified Key of a Document
+//
+// HTML Markup: <FieldTextBox Doc={Document's ID} FieldKey={Key's name + "Key"}
+//
+// In Code, the node's HTML is specified in the document's parameterized structure as:
+// document.SetField(KeyStore.Layout, "<FieldTextBox doc={doc} fieldKey={<KEYNAME>Key} />");
+// and the node's binding to the specified document KEYNAME as:
+// document.SetField(KeyStore.LayoutKeys, new ListField([KeyStore.<KEYNAME>]));
+// The Jsx parser at run time will bind:
+// 'fieldKey' property to the Key stored in LayoutKeys
+// and 'doc' property to the document that is being rendered
+//
+// When rendered() by React, this extracts the TextController from the Document stored at the
+// specified Key and assigns it to an HTML input node. When changes are made tot his node,
+// this will edit the document and assign the new value to that field.
+//
@observer
export class FieldTextBox extends React.Component<IProps, IProps> {
- readonly doc:Document;
- readonly fieldKey:Key;
constructor(props:IProps) {
super(props);
- this.doc = props.doc;
- this.fieldKey = props.fieldKey;
this.onChange = this.onChange.bind(this);
}