From fed460a9dffd85b32e30aeb112f2c7c47371bce6 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Fri, 22 Feb 2019 03:01:30 -0500 Subject: Added CollectionView Switched sub-collections to not inherit from CollectionViewBase --- src/client/Server.ts | 5 +- src/client/documents/Documents.ts | 81 +++++--------- src/client/views/Main.tsx | 8 +- .../views/collections/CollectionDockingView.tsx | 11 +- .../views/collections/CollectionFreeFormView.tsx | 25 ++--- .../views/collections/CollectionSchemaView.tsx | 13 ++- src/client/views/collections/CollectionView.tsx | 116 +++++++++++++++++++++ .../views/collections/CollectionViewBase.tsx | 61 ----------- src/client/views/nodes/DocumentView.tsx | 13 ++- src/client/views/nodes/FieldView.tsx | 3 +- src/fields/BasicField.ts | 6 +- src/fields/Document.ts | 9 ++ src/fields/KeyStore.ts | 1 + src/fields/ListField.ts | 19 +++- 14 files changed, 212 insertions(+), 159 deletions(-) create mode 100644 src/client/views/collections/CollectionView.tsx delete mode 100644 src/client/views/collections/CollectionViewBase.tsx (limited to 'src') 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) => { 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, 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('
')); 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, options: DocumentOptions = {}, id?: string): Document { + export function CollectionDocument(data: Array | 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, options: DocumentOptions, id?: string) { + return CollectionDocument(documents, CollectionViewType.Freeform, options, id) + } + + export function SchemaDocument(documents: Array, 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(KeyStore.Data, []).push(Documents.CollectionDocument([], { + mainfreeform.GetList(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 { 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(); 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 { private _canvasRef = React.createRef(); 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 (); + ContainingCollectionView={this.props.CollectionView} />); })}
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 { private _mainCont = React.createRef(); 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 }) =>
+ ContainingCollectionView={this.props.CollectionView} />
} 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; +} + +export enum CollectionViewType { + Invalid, + Freeform, + Schema, + Docking, +} + +export const COLLECTION_BORDER_WIDTH = 2; + +@observer +export class CollectionView extends React.Component { + + public static LayoutString(fieldKey: string = "DataKey") { + return ``; + } + 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()) + 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()) + 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 === "") { + 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 () + case CollectionViewType.Schema: + return () + case CollectionViewType.Docking: + return () + default: + return
+ } + } +} \ 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 { - - 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()) - 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()) - 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; + ContainingCollectionView: Opt; Document: Document; AddDocument?: (doc: Document) => void; @@ -114,7 +114,7 @@ export class DocumentView extends React.Component { @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 { 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 { let backgroundLayout = this.backgroundLayout; if (backgroundLayout) { let backgroundView = () => ( { onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} > boolean; + select: () => void; isTopMost: boolean; } @observer export class FieldView extends React.Component { - 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 { 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 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 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(key: Key, ctor: { new(...args: any[]): T }, ignoreProto: boolean = false): FieldValue { 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 extends BasicField { if (save) { Server.UpdateField(this); } - observe(this.Data as IObservableArray, (change: IArrayChange | IArraySplice) => { + this.observeList(); + } + + private observeDisposer: Lambda | undefined; + private observeList(): void { + this.observeDisposer = observe(this.Data as IObservableArray, (change: IArrayChange | IArraySplice) => { this.updateProxies() if (change.type == "splice") { UndoManager.AddEvent({ @@ -27,7 +32,15 @@ export class ListField extends BasicField { }) } Server.UpdateField(this); - }) + }); + } + + protected setData(value: T[]) { + if (this.observeDisposer) { + this.observeDisposer() + } + this.data = observable(value); + this.observeList(); } private updateProxies() { -- cgit v1.2.3-70-g09d2