aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTyler Schicke <tyler_schicke@brown.edu>2019-02-22 03:01:30 -0500
committerTyler Schicke <tyler_schicke@brown.edu>2019-02-22 03:01:30 -0500
commitfed460a9dffd85b32e30aeb112f2c7c47371bce6 (patch)
tree16f8c1d9b4a5e3e4e1b22e6b6520b793801c8b28
parent3f9e4363e6601eac175ff71192d414fd6051d921 (diff)
Added CollectionView
Switched sub-collections to not inherit from CollectionViewBase
-rw-r--r--src/client/Server.ts5
-rw-r--r--src/client/documents/Documents.ts81
-rw-r--r--src/client/views/Main.tsx8
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx11
-rw-r--r--src/client/views/collections/CollectionFreeFormView.tsx25
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx13
-rw-r--r--src/client/views/collections/CollectionView.tsx116
-rw-r--r--src/client/views/collections/CollectionViewBase.tsx61
-rw-r--r--src/client/views/nodes/DocumentView.tsx13
-rw-r--r--src/client/views/nodes/FieldView.tsx3
-rw-r--r--src/fields/BasicField.ts6
-rw-r--r--src/fields/Document.ts9
-rw-r--r--src/fields/KeyStore.ts1
-rw-r--r--src/fields/ListField.ts19
14 files changed, 212 insertions, 159 deletions
diff --git a/src/client/Server.ts b/src/client/Server.ts
index 3e61729ab..06ac22c61 100644
--- a/src/client/Server.ts
+++ b/src/client/Server.ts
@@ -60,13 +60,16 @@ export class Server {
});
}
- public static GetDocumentField(doc: Document, key: Key) {
+ public static GetDocumentField(doc: Document, key: Key, callback?: (field: Field) => void) {
let field = doc._proxies.get(key.Id);
if (field) {
this.GetField(field,
action((fieldfromserver: Opt<Field>) => {
if (fieldfromserver) {
doc.fields.set(key.Id, { key, field: fieldfromserver });
+ if (callback) {
+ callback(fieldfromserver);
+ }
}
}));
}
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 920068273..bfa6cb7a9 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -11,6 +11,7 @@ import { ImageField } from "../../fields/ImageField";
import { ImageBox } from "../views/nodes/ImageBox";
import { CollectionFreeFormView } from "../views/collections/CollectionFreeFormView";
import { FieldId } from "../../fields/Field";
+import { CollectionView, CollectionViewType } from "../views/collections/CollectionView";
interface DocumentOptions {
x?: number;
@@ -24,12 +25,10 @@ interface DocumentOptions {
export namespace Documents {
export function initProtos(callback: () => void) {
- Server.GetFields([collectionProtoId, textProtoId, imageProtoId, schemaProtoId, dockProtoId], (fields) => {
+ Server.GetFields([collectionProtoId, textProtoId, imageProtoId], (fields) => {
collectionProto = fields[collectionProtoId] as Document;
imageProto = fields[imageProtoId] as Document;
textProto = fields[textProtoId] as Document;
- dockProto = fields[dockProtoId] as Document;
- schemaProto = fields[schemaProtoId] as Document;
callback()
});
}
@@ -83,52 +82,6 @@ export namespace Documents {
return doc;
}
- let schemaProto: Document;
- const schemaProtoId = "schemaProto";
- function GetSchemaPrototype(): Document {
- if (!schemaProto) {
- schemaProto = new Document(schemaProtoId);
- schemaProto.Set(KeyStore.X, new NumberField(0));
- schemaProto.Set(KeyStore.Y, new NumberField(0));
- schemaProto.Set(KeyStore.Width, new NumberField(300));
- schemaProto.Set(KeyStore.Height, new NumberField(150));
- schemaProto.Set(KeyStore.Layout, new TextField(CollectionSchemaView.LayoutString()));
- schemaProto.Set(KeyStore.LayoutKeys, new ListField([KeyStore.Data]));
- }
- return schemaProto;
- }
-
- export function SchemaDocument(documents: Array<Document>, options: DocumentOptions = {}): Document {
- let doc = GetSchemaPrototype().MakeDelegate();
- setupOptions(doc, options);
- doc.Set(KeyStore.Data, new ListField(documents));
- return doc;
- }
-
-
- let dockProto: Document;
- const dockProtoId = "dockProto";
- function GetDockPrototype(): Document {
- if (!dockProto) {
- dockProto = new Document();
- dockProto.Set(KeyStore.X, new NumberField(0));
- dockProto.Set(KeyStore.Y, new NumberField(0));
- dockProto.Set(KeyStore.Width, new NumberField(300));
- dockProto.Set(KeyStore.Height, new NumberField(150));
- dockProto.Set(KeyStore.Layout, new TextField(CollectionDockingView.LayoutString()));
- dockProto.Set(KeyStore.LayoutKeys, new ListField([KeyStore.Data]));
- }
- return dockProto;
- }
-
- export function DockDocument(config: string, options: DocumentOptions = {}, id?: string): Document {
- let doc = GetDockPrototype().MakeDelegate(id);
- setupOptions(doc, options);
- doc.SetText(KeyStore.Data, config);
- return doc;
- }
-
-
let imageProto: Document;
const imageProtoId = "imageProto";
function GetImagePrototype(): Document {
@@ -141,7 +94,8 @@ export namespace Documents {
imageProto.Set(KeyStore.NativeHeight, new NumberField(300));
imageProto.Set(KeyStore.Width, new NumberField(300));
imageProto.Set(KeyStore.Height, new NumberField(300));
- imageProto.Set(KeyStore.Layout, new TextField(CollectionFreeFormView.LayoutString("AnnotationsKey")));
+ imageProto.Set(KeyStore.Layout, new TextField(CollectionView.LayoutString("AnnotationsKey")));
+ imageProto.SetNumber(KeyStore.ViewType, CollectionViewType.Freeform)
imageProto.Set(KeyStore.BackgroundLayout, new TextField(ImageBox.LayoutString()));
// imageProto.SetField(KeyStore.Layout, new TextField('<div style={"background-image: " + {Data}} />'));
imageProto.Set(KeyStore.LayoutKeys, new ListField([KeyStore.Data, KeyStore.Annotations]));
@@ -165,23 +119,36 @@ export namespace Documents {
function GetCollectionPrototype(): Document {
if (!collectionProto) {
collectionProto = new Document(collectionProtoId);
- collectionProto.Set(KeyStore.X, new NumberField(0));
- collectionProto.Set(KeyStore.Y, new NumberField(0));
collectionProto.Set(KeyStore.Scale, new NumberField(1));
collectionProto.Set(KeyStore.PanX, new NumberField(0));
collectionProto.Set(KeyStore.PanY, new NumberField(0));
- collectionProto.Set(KeyStore.Width, new NumberField(300));
- collectionProto.Set(KeyStore.Height, new NumberField(300));
- collectionProto.Set(KeyStore.Layout, new TextField(CollectionFreeFormView.LayoutString("DataKey")));
+ collectionProto.Set(KeyStore.Layout, new TextField(CollectionView.LayoutString("DataKey")));
collectionProto.Set(KeyStore.LayoutKeys, new ListField([KeyStore.Data]));
}
return collectionProto;
}
- export function CollectionDocument(documents: Array<Document>, options: DocumentOptions = {}, id?: string): Document {
+ export function CollectionDocument(data: Array<Document> | string, viewType: CollectionViewType, options: DocumentOptions = {}, id?: string): Document {
let doc = GetCollectionPrototype().MakeDelegate(id);
setupOptions(doc, options);
- doc.Set(KeyStore.Data, new ListField(documents));
+ if (typeof data === "string") {
+ doc.SetText(KeyStore.Data, data);
+ } else {
+ doc.SetData(KeyStore.Data, data, ListField);
+ }
+ doc.SetNumber(KeyStore.ViewType, viewType);
return doc;
}
+
+ export function FreeformDocument(documents: Array<Document>, options: DocumentOptions, id?: string) {
+ return CollectionDocument(documents, CollectionViewType.Freeform, options, id)
+ }
+
+ export function SchemaDocument(documents: Array<Document>, options: DocumentOptions, id?: string) {
+ return CollectionDocument(documents, CollectionViewType.Schema, options, id)
+ }
+
+ export function DockDocument(config: string, options: DocumentOptions, id?: string) {
+ return CollectionDocument(config, CollectionViewType.Docking, options, id)
+ }
} \ No newline at end of file
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index c7a6a44e8..fe1a999ec 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -61,16 +61,14 @@ Documents.initProtos(() => {
let mainfreeform: Document;
if (res) {
mainContainer = ServerUtils.FromJson(res) as Document;
- mainfreeform = mainContainer.Get(KeyStore.ActiveFrame) as Document;
- if (!mainfreeform)
- Server.GetField(mainContainer._proxies.get(KeyStore.ActiveFrame.Id)!, (field) => mainfreeform = field as Document);
+ mainContainer.GetAsync(KeyStore.ActiveFrame, field => mainfreeform = field as Document);
}
else {
mainContainer = Documents.DockDocument(JSON.stringify({ content: [{ type: 'row', content: [] }] }), { title: "main container" }, mainDocId);
Utils.Emit(Server.Socket, MessageStore.AddDocument, new DocumentTransfer(mainContainer.ToJson()))
setTimeout(() => {
- mainfreeform = Documents.CollectionDocument([], { x: 0, y: 400, title: "mini collection" });
+ mainfreeform = Documents.FreeformDocument([], { x: 0, y: 400, title: "mini collection" });
Utils.Emit(Server.Socket, MessageStore.AddDocument, new DocumentTransfer(mainfreeform.ToJson()));
var docs = [mainfreeform].map(doc => CollectionDockingView.makeDocumentConfig(doc));
@@ -90,7 +88,7 @@ Documents.initProtos(() => {
}));
})
let addColNode = action(() => {
- mainfreeform.GetList<Document>(KeyStore.Data, []).push(Documents.CollectionDocument([], {
+ mainfreeform.GetList<Document>(KeyStore.Data, []).push(Documents.FreeformDocument([], {
x: 0, y: 300, width: 200, height: 200, title: "added note"
}));
})
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 60dc24b5f..6d91aef5e 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -14,13 +14,12 @@ import { DragManager } from "../../util/DragManager";
import { undoBatch } from "../../util/UndoManager";
import { DocumentView } from "../nodes/DocumentView";
import "./CollectionDockingView.scss";
-import { CollectionViewBase, CollectionViewProps, COLLECTION_BORDER_WIDTH } from "./CollectionViewBase";
+import { CollectionViewProps, COLLECTION_BORDER_WIDTH, SubCollectionViewProps } from "./CollectionView";
import React = require("react");
@observer
-export class CollectionDockingView extends CollectionViewBase {
+export class CollectionDockingView extends React.Component<SubCollectionViewProps> {
public static Instance: CollectionDockingView;
- public static LayoutString() { return CollectionViewBase.LayoutString("CollectionDockingView"); }
public static makeDocumentConfig(document: Document) {
return {
type: 'react-component',
@@ -41,7 +40,7 @@ export class CollectionDockingView extends CollectionViewBase {
private _containerRef = React.createRef<HTMLDivElement>();
private _fullScreen: any = null;
- constructor(props: CollectionViewProps) {
+ constructor(props: SubCollectionViewProps) {
super(props);
CollectionDockingView.Instance = this;
(window as any).React = React;
@@ -187,7 +186,7 @@ export class CollectionDockingView extends CollectionViewBase {
}
@action
onPointerDown = (e: React.PointerEvent): void => {
- if (e.button === 2 && this.active) {
+ if (e.button === 2 && this.props.active()) {
e.stopPropagation();
e.preventDefault();
} else {
@@ -195,7 +194,7 @@ export class CollectionDockingView extends CollectionViewBase {
if (className == "lm_drag_handle" || className == "lm_close" || className == "lm_maximise" || className == "lm_minimise" || className == "lm_close_tab") {
this._flush = true;
}
- if (e.buttons === 1 && this.active) {
+ if (e.buttons === 1 && this.props.active()) {
e.stopPropagation();
}
}
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index 986bcdcee..bd7ca5b6f 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -4,7 +4,7 @@ import { action, computed } from "mobx";
import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
import { DragManager } from "../../util/DragManager";
import "./CollectionFreeFormView.scss";
-import { CollectionViewBase, COLLECTION_BORDER_WIDTH, CollectionViewProps } from "./CollectionViewBase";
+import { COLLECTION_BORDER_WIDTH, CollectionViewProps, SubCollectionViewProps } from "./CollectionView";
import { KeyStore } from "../../../fields/KeyStore";
import { Document } from "../../../fields/Document";
import { ListField } from "../../../fields/ListField";
@@ -16,8 +16,7 @@ import { DocumentView } from "../nodes/DocumentView";
import { undoBatch } from "../../util/UndoManager";
@observer
-export class CollectionFreeFormView extends CollectionViewBase {
- public static LayoutString(fieldKey: string = "DataKey") { return CollectionViewBase.LayoutString("CollectionFreeFormView", fieldKey); }
+export class CollectionFreeFormView extends React.Component<SubCollectionViewProps> {
private _canvasRef = React.createRef<HTMLDivElement>();
private _lastX: number = 0;
private _lastY: number = 0;
@@ -38,7 +37,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
@computed
get resizeScaling() { return this.isAnnotationOverlay ? this.props.Document.GetNumber(KeyStore.Width, 0) / this.nativeWidth : 1; }
- constructor(props: CollectionViewProps) {
+ constructor(props: SubCollectionViewProps) {
super(props);
}
@@ -46,9 +45,11 @@ export class CollectionFreeFormView extends CollectionViewBase {
@action
drop = (e: Event, de: DragManager.DropEvent) => {
const doc: DocumentView = de.data["document"];
- if (doc.props.ContainingCollectionView && doc.props.ContainingCollectionView !== this) {
- doc.props.ContainingCollectionView.removeDocument(doc.props.Document);
- this.addDocument(doc.props.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;
@@ -79,7 +80,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
@action
onPointerDown = (e: React.PointerEvent): void => {
- if ((e.button === 2 && this.active) ||
+ if ((e.button === 2 && this.props.active()) ||
!e.defaultPrevented) {
document.removeEventListener("pointermove", this.onPointerMove);
document.addEventListener("pointermove", this.onPointerMove);
@@ -104,7 +105,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
@action
onPointerMove = (e: PointerEvent): void => {
- if (!e.cancelBubble && this.active) {
+ if (!e.cancelBubble && this.props.active()) {
e.preventDefault();
e.stopPropagation();
let x = this.props.Document.GetNumber(KeyStore.PanX, 0);
@@ -248,13 +249,13 @@ export class CollectionFreeFormView extends CollectionViewBase {
{this.props.BackgroundView ? this.props.BackgroundView() : null}
{lvalue.Data.map(doc => {
return (<CollectionFreeFormDocumentView key={doc.Id} Document={doc}
- AddDocument={this.addDocument}
- RemoveDocument={this.removeDocument}
+ AddDocument={this.props.addDocument}
+ RemoveDocument={this.props.removeDocument}
ScreenToLocalTransform={this.getTransform}
isTopMost={false}
Scaling={1}
PanelSize={[doc.GetNumber(KeyStore.Width, 0), doc.GetNumber(KeyStore.Height, 0)]}
- ContainingCollectionView={this} />);
+ ContainingCollectionView={this.props.CollectionView} />);
})}
</div>
</div>
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 5ec288b13..9405c820f 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -13,12 +13,10 @@ import { EditableView } from "../EditableView";
import { DocumentView } from "../nodes/DocumentView";
import { FieldView, FieldViewProps } from "../nodes/FieldView";
import "./CollectionSchemaView.scss";
-import { CollectionViewBase, COLLECTION_BORDER_WIDTH } from "./CollectionViewBase";
+import { COLLECTION_BORDER_WIDTH, CollectionViewProps, SubCollectionViewProps } from "./CollectionView";
@observer
-export class CollectionSchemaView extends CollectionViewBase {
- public static LayoutString(fieldKey: string = "DataKey") { return CollectionViewBase.LayoutString("CollectionSchemaView", fieldKey); }
-
+export class CollectionSchemaView extends React.Component<SubCollectionViewProps> {
private _mainCont = React.createRef<HTMLDivElement>();
private DIVIDER_WIDTH = 5;
@@ -34,6 +32,7 @@ export class CollectionSchemaView extends CollectionViewBase {
doc: rowProps.value[0],
fieldKey: rowProps.value[1],
isSelected: () => false,
+ select: () => { },
isTopMost: false
}
let contents = (
@@ -112,7 +111,7 @@ export class CollectionSchemaView extends CollectionViewBase {
// e.preventDefault();
// } else
{
- if (e.buttons === 1 && this.active) {
+ if (e.buttons === 1 && this.props.active()) {
e.stopPropagation();
}
}
@@ -145,12 +144,12 @@ export class CollectionSchemaView extends CollectionViewBase {
{({ measureRef }) =>
<div ref={measureRef}>
<DocumentView Document={selected}
- AddDocument={this.addDocument} RemoveDocument={this.removeDocument}
+ AddDocument={this.props.addDocument} RemoveDocument={this.props.removeDocument}
ScreenToLocalTransform={this.getTransform}
Scaling={this._parentScaling}
isTopMost={false}
PanelSize={[this._panelWidth, this._panelHeight]}
- ContainingCollectionView={me} />
+ ContainingCollectionView={this.props.CollectionView} />
</div>
}
</Measure>
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
new file mode 100644
index 000000000..651d85879
--- /dev/null
+++ b/src/client/views/collections/CollectionView.tsx
@@ -0,0 +1,116 @@
+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";
+
+
+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,
+ Freeform,
+ Schema,
+ Docking,
+}
+
+export const COLLECTION_BORDER_WIDTH = 2;
+
+@observer
+export class CollectionView extends React.Component<CollectionViewProps> {
+
+ public static LayoutString(fieldKey: string = "DataKey") {
+ return `<CollectionView Document={Document}
+ ScreenToLocalTransform={ScreenToLocalTransform} fieldKey={${fieldKey}} isSelected={isSelected} select={select}
+ isTopMost={isTopMost} BackgroundView={BackgroundView} />`;
+ }
+ public active = () => {
+ var isSelected = this.props.isSelected();
+ var childSelected = SelectionManager.SelectedDocuments().some(view => view.props.ContainingCollectionView == this);
+ var topMost = this.props.isTopMost;
+ return isSelected || childSelected || topMost;
+ }
+ @action
+ addDocument = (doc: Document): void => {
+ //TODO This won't create the field if it doesn't already exist
+ const value = this.props.Document.GetData(this.props.fieldKey, ListField, new Array<Document>())
+ value.push(doc);
+ }
+
+ @action
+ removeDocument = (doc: Document): boolean => {
+ //TODO This won't create the field if it doesn't already exist
+ const value = this.props.Document.GetData(this.props.fieldKey, ListField, new Array<Document>())
+ let index = value.indexOf(doc);
+ if (index !== -1) {
+ value.splice(index, 1)
+
+ SelectionManager.DeselectAll()
+ ContextMenu.Instance.clearItems()
+ return true;
+ }
+ return false
+ }
+
+ get collectionViewType(): CollectionViewType {
+ let Document = this.props.Document;
+ let viewField = Document.GetT(KeyStore.ViewType, NumberField);
+ if (viewField === "<Waiting>") {
+ return CollectionViewType.Invalid;
+ } else if (viewField) {
+ return viewField.Data;
+ } else {
+ return CollectionViewType.Freeform;
+ }
+ }
+
+ set collectionViewType(type: CollectionViewType) {
+ let Document = this.props.Document;
+ Document.SetData(KeyStore.ViewType, type, NumberField);
+ }
+
+ render() {
+ let viewType = this.collectionViewType;
+ switch (viewType) {
+ case CollectionViewType.Freeform:
+ return (<CollectionFreeFormView {...this.props}
+ addDocument={this.addDocument} removeDocument={this.removeDocument} active={this.active}
+ CollectionView={this} />)
+ case CollectionViewType.Schema:
+ return (<CollectionSchemaView {...this.props}
+ addDocument={this.addDocument} removeDocument={this.removeDocument} active={this.active}
+ CollectionView={this} />)
+ case CollectionViewType.Docking:
+ return (<CollectionDockingView {...this.props}
+ addDocument={this.addDocument} removeDocument={this.removeDocument} active={this.active}
+ CollectionView={this} />)
+ default:
+ return <div></div>
+ }
+ }
+} \ No newline at end of file
diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx
deleted file mode 100644
index 0acc890d8..000000000
--- a/src/client/views/collections/CollectionViewBase.tsx
+++ /dev/null
@@ -1,61 +0,0 @@
-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";
-
-
-export interface CollectionViewProps {
- fieldKey: Key;
- Document: Document;
- ScreenToLocalTransform: () => Transform;
- isSelected: () => boolean;
- isTopMost: boolean;
- select: (ctrlPressed: boolean) => void;
- BackgroundView?: () => JSX.Element;
-}
-
-export const COLLECTION_BORDER_WIDTH = 2;
-
-@observer
-export class CollectionViewBase extends React.Component<CollectionViewProps> {
-
- public static LayoutString(collectionType: string, fieldKey: string = "DataKey") {
- return `<${collectionType} Document={Document}
- ScreenToLocalTransform={ScreenToLocalTransform} fieldKey={${fieldKey}} isSelected={isSelected} select={select}
- isTopMost={isTopMost} BackgroundView={BackgroundView} />`;
- }
- @computed
- public get active(): boolean {
- var isSelected = this.props.isSelected();
- var childSelected = SelectionManager.SelectedDocuments().some(view => view.props.ContainingCollectionView == this);
- var topMost = this.props.isTopMost;
- return isSelected || childSelected || topMost;
- }
- @action
- addDocument = (doc: Document): void => {
- //TODO This won't create the field if it doesn't already exist
- const value = this.props.Document.GetData(this.props.fieldKey, ListField, new Array<Document>())
- value.push(doc);
- }
-
- @action
- removeDocument = (doc: Document): boolean => {
- //TODO This won't create the field if it doesn't already exist
- const value = this.props.Document.GetData(this.props.fieldKey, ListField, new Array<Document>())
- let index = value.indexOf(doc);
- if (index !== -1) {
- value.splice(index, 1)
-
- SelectionManager.DeselectAll()
- ContextMenu.Instance.clearItems()
- return true;
- }
- return false
- }
-
-} \ No newline at end of file
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 7cf00a116..2114a5697 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -9,7 +9,7 @@ import { Utils } from "../../../Utils";
import { CollectionDockingView } from "../collections/CollectionDockingView";
import { CollectionFreeFormView } from "../collections/CollectionFreeFormView";
import { CollectionSchemaView } from "../collections/CollectionSchemaView";
-import { CollectionViewBase, COLLECTION_BORDER_WIDTH } from "../collections/CollectionViewBase";
+import { COLLECTION_BORDER_WIDTH, CollectionView, CollectionViewType } from "../collections/CollectionView";
import { FormattedTextBox } from "../nodes/FormattedTextBox";
import { ImageBox } from "../nodes/ImageBox";
import "./DocumentView.scss";
@@ -22,7 +22,7 @@ import { TextField } from "../../../fields/TextField";
const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this?
export interface DocumentViewProps {
- ContainingCollectionView: Opt<CollectionViewBase>;
+ ContainingCollectionView: Opt<CollectionView>;
Document: Document;
AddDocument?: (doc: Document) => void;
@@ -114,7 +114,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
@computed
get active(): boolean {
return SelectionManager.IsSelected(this) || !this.props.ContainingCollectionView ||
- this.props.ContainingCollectionView.active;
+ this.props.ContainingCollectionView.active();
}
private _contextMenuCanOpen = false;
@@ -233,6 +233,9 @@ export class DocumentView extends React.Component<DocumentViewProps> {
ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked })
ContextMenu.Instance.addItem({ description: "Open Right", event: this.openRight })
ContextMenu.Instance.addItem({ description: "Delete", event: this.deleteClicked })
+ ContextMenu.Instance.addItem({ description: "Freeform", event: () => { this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Freeform) } })
+ ContextMenu.Instance.addItem({ description: "Schema", event: () => { this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Schema) } })
+ ContextMenu.Instance.addItem({ description: "Docking", event: () => { this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Docking) } })
ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15)
SelectionManager.SelectDoc(this, e.ctrlKey);
}
@@ -275,7 +278,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
let backgroundLayout = this.backgroundLayout;
if (backgroundLayout) {
let backgroundView = () => (<JsxParser
- components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }}
+ components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView }}
bindings={documentBindings}
jsx={this.backgroundLayout}
showWarnings={true}
@@ -294,7 +297,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
onContextMenu={this.onContextMenu}
onPointerDown={this.onPointerDown} >
<JsxParser
- components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }}
+ components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView }}
bindings={documentBindings}
jsx={this.layout}
showWarnings={true}
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 918acff4c..821172d71 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -20,12 +20,13 @@ export interface FieldViewProps {
fieldKey: Key;
doc: Document;
isSelected: () => boolean;
+ select: () => void;
isTopMost: boolean;
}
@observer
export class FieldView extends React.Component<FieldViewProps> {
- public static LayoutString(fieldType: { name: string }) { return `<${fieldType.name} doc={Document} DocumentViewForField={DocumentView} fieldKey={DataKey} isSelected={isSelected} isTopMost={isTopMost} />`; }
+ public static LayoutString(fieldType: { name: string }) { return `<${fieldType.name} doc={Document} DocumentViewForField={DocumentView} fieldKey={DataKey} isSelected={isSelected} select={select} isTopMost={isTopMost} />`; }
@computed
get field(): FieldValue<Field> {
const { doc, fieldKey } = this.props;
diff --git a/src/fields/BasicField.ts b/src/fields/BasicField.ts
index 91977b243..a92c4a236 100644
--- a/src/fields/BasicField.ts
+++ b/src/fields/BasicField.ts
@@ -32,7 +32,7 @@ export abstract class BasicField<T> extends Field {
return;
}
let oldValue = this.data;
- this.data = value;
+ this.setData(value);
UndoManager.AddEvent({
undo: () => this.Data = oldValue,
redo: () => this.Data = value
@@ -40,6 +40,10 @@ export abstract class BasicField<T> extends Field {
Server.UpdateField(this);
}
+ protected setData(value: T) {
+ this.data = value;
+ }
+
@action
TrySetValue(value: any): boolean {
if (typeof value == typeof this.data) {
diff --git a/src/fields/Document.ts b/src/fields/Document.ts
index 6667485b6..ff13732b3 100644
--- a/src/fields/Document.ts
+++ b/src/fields/Document.ts
@@ -90,6 +90,15 @@ export class Document extends Field {
return field;
}
+ GetAsync(key: Key, callback: (field: Field) => void): boolean {
+ //This currently doesn't deal with prototypes
+ if (this._proxies.has(key.Id)) {
+ Server.GetDocumentField(this, key, callback);
+ return true;
+ }
+ return false;
+ }
+
GetT<T extends Field = Field>(key: Key, ctor: { new(...args: any[]): T }, ignoreProto: boolean = false): FieldValue<T> {
var getfield = this.Get(key, ignoreProto);
if (getfield != FieldWaiting) {
diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts
index 7056886aa..6d6c6a546 100644
--- a/src/fields/KeyStore.ts
+++ b/src/fields/KeyStore.ts
@@ -16,6 +16,7 @@ export namespace KeyStore {
export const ZIndex = new Key("ZIndex");
export const Data = new Key("Data");
export const Annotations = new Key("Annotations");
+ export const ViewType = new Key("ViewType");
export const Layout = new Key("Layout");
export const BackgroundLayout = new Key("BackgroundLayout");
export const LayoutKeys = new Key("LayoutKeys");
diff --git a/src/fields/ListField.ts b/src/fields/ListField.ts
index 75c2eb343..700600804 100644
--- a/src/fields/ListField.ts
+++ b/src/fields/ListField.ts
@@ -1,4 +1,4 @@
-import { action, IArrayChange, IArraySplice, IObservableArray, observe } from "mobx";
+import { action, IArrayChange, IArraySplice, IObservableArray, observe, observable, Lambda } from "mobx";
import { Server } from "../client/Server";
import { UndoManager } from "../client/util/UndoManager";
import { Types } from "../server/Message";
@@ -13,7 +13,12 @@ export class ListField<T extends Field> extends BasicField<T[]> {
if (save) {
Server.UpdateField(this);
}
- observe(this.Data as IObservableArray<T>, (change: IArrayChange<T> | IArraySplice<T>) => {
+ this.observeList();
+ }
+
+ private observeDisposer: Lambda | undefined;
+ private observeList(): void {
+ this.observeDisposer = observe(this.Data as IObservableArray<T>, (change: IArrayChange<T> | IArraySplice<T>) => {
this.updateProxies()
if (change.type == "splice") {
UndoManager.AddEvent({
@@ -27,7 +32,15 @@ export class ListField<T extends Field> extends BasicField<T[]> {
})
}
Server.UpdateField(this);
- })
+ });
+ }
+
+ protected setData(value: T[]) {
+ if (this.observeDisposer) {
+ this.observeDisposer()
+ }
+ this.data = observable(value);
+ this.observeList();
}
private updateProxies() {