From 3c71a4b9c727f8eee8631b46b28c010682608f13 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Sat, 16 Feb 2019 07:46:55 -0500 Subject: Fixed server and added a field debug viewer --- src/fields/KeyStore.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/fields/KeyStore.ts (limited to 'src/fields/KeyStore.ts') diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts new file mode 100644 index 000000000..1e0b12729 --- /dev/null +++ b/src/fields/KeyStore.ts @@ -0,0 +1,24 @@ +import { Key } from "./Key"; + +export namespace KeyStore { + export const Prototype = new Key("Prototype"); + export const X = new Key("X"); + export const Y = new Key("Y"); + export const Title = new Key("Title"); + export const Author = new Key("Author"); + export const PanX = new Key("PanX"); + export const PanY = new Key("PanY"); + export const Scale = new Key("Scale"); + export const Width = new Key("Width"); + export const Height = new Key("Height"); + export const ZIndex = new Key("ZIndex"); + export const Data = new Key("Data"); + export const Layout = new Key("Layout"); + export const LayoutKeys = new Key("LayoutKeys"); + export const LayoutFields = new Key("LayoutFields"); + export const ColumnsKey = new Key("SchemaColumns"); + + export function Get(name: string): Key { + return new Key(name) + } +} -- cgit v1.2.3-70-g09d2 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/fields/KeyStore.ts') 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 From 451c31e529dad9fbec94e71790907848f7c3fb24 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sat, 23 Feb 2019 02:34:58 -0500 Subject: css hacking to fix layout issues related to making a captioned image style --- src/client/documents/Documents.ts | 20 ++++++++++++++++---- .../views/collections/CollectionFreeFormView.scss | 2 ++ .../views/collections/CollectionFreeFormView.tsx | 5 +++-- src/client/views/nodes/FieldView.tsx | 3 ++- src/client/views/nodes/FormattedTextBox.scss | 4 ++-- src/client/views/nodes/FormattedTextBox.tsx | 5 ++--- src/client/views/nodes/ImageBox.scss | 3 ++- src/fields/KeyStore.ts | 1 + 8 files changed, 30 insertions(+), 13 deletions(-) (limited to 'src/fields/KeyStore.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 156a09316..6ec5aa711 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -5,13 +5,10 @@ import { TextField } from "../../fields/TextField"; import { NumberField } from "../../fields/NumberField"; import { ListField } from "../../fields/ListField"; import { FormattedTextBox } from "../views/nodes/FormattedTextBox"; -import { CollectionDockingView } from "../views/collections/CollectionDockingView"; -import { CollectionSchemaView } from "../views/collections/CollectionSchemaView"; 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"; +import { FieldView } from "../views/nodes/FieldView"; export interface DocumentOptions { x?: number; @@ -102,12 +99,27 @@ export namespace Documents { return imageProto; } return imageProto; + } + // example of custom display string for an image that shows a caption. + function CaptionLayoutString() { + return `
+
` + + ImageBox.LayoutString() + + `
+
` + + FormattedTextBox.LayoutString("CaptionKey") + + `
+
` }; + export function ImageDocument(url: string, options: DocumentOptions = {}): Document { let doc = GetImagePrototype().MakeDelegate(); setupOptions(doc, options); doc.Set(KeyStore.Data, new ImageField(new URL(url))); + doc.Set(KeyStore.Caption, new TextField("my caption...")); + doc.Set(KeyStore.BackgroundLayout, new TextField(CaptionLayoutString())); + doc.Set(KeyStore.LayoutKeys, new ListField([KeyStore.Data, KeyStore.Annotations, KeyStore.Caption])); let annotation = Documents.TextDocument({ title: "hello" }); doc.Set(KeyStore.Annotations, new ListField([annotation])); diff --git a/src/client/views/collections/CollectionFreeFormView.scss b/src/client/views/collections/CollectionFreeFormView.scss index 4cf474f77..6d678528a 100644 --- a/src/client/views/collections/CollectionFreeFormView.scss +++ b/src/client/views/collections/CollectionFreeFormView.scss @@ -11,5 +11,7 @@ position: absolute; top: 0; left: 0; + width:100%; + height: 100% } } \ No newline at end of file diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index c12a82617..6d2662105 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -34,7 +34,7 @@ export class CollectionFreeFormView extends CollectionViewBase { @computed get panX(): number { return this.props.Document.GetNumber(KeyStore.PanX, 0) } @computed get panY(): number { return this.props.Document.GetNumber(KeyStore.PanY, 0) } @computed get scale(): number { return this.props.Document.GetNumber(KeyStore.Scale, 1); } - @computed get isAnnotationOverlay() { return this.props.fieldKey == KeyStore.Annotations; } + @computed get isAnnotationOverlay() { return this.props.fieldKey.Id === KeyStore.Annotations.Id; } // bcz: ? Why do we need to compare Id's? @computed get nativeWidth() { return this.props.Document.GetNumber(KeyStore.NativeWidth, 0); } @computed get nativeHeight() { return this.props.Document.GetNumber(KeyStore.NativeHeight, 0); } @computed get zoomScaling() { return this.props.Document.GetNumber(KeyStore.Scale, 1); } @@ -91,6 +91,7 @@ export class CollectionFreeFormView extends CollectionViewBase { let [dx, dy] = this.props.ScreenToLocalTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY); this.SetPan(x + dx, y + dy); + console.log("px = " + x + " " + y) } this._lastX = e.pageX; this._lastY = e.pageY; @@ -209,7 +210,7 @@ export class CollectionFreeFormView extends CollectionViewBase { style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px`, }} ref={this.createDropTarget}>
{this.backgroundView} {this.views} diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 97d3f2a85..9dda08d8d 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -27,7 +27,8 @@ export interface FieldViewProps { @observer export class FieldView extends React.Component { - public static LayoutString(fieldType: { name: string }) { return `<${fieldType.name} doc={Document} DocumentViewForField={DocumentView} bindings={bindings} fieldKey={DataKey} isSelected={isSelected} select={select} isTopMost={isTopMost} />`; } + public static LayoutString(fieldType: { name: string }, fieldStr: string = "DataKey") { return `<${fieldType.name} doc={Document} DocumentViewForField={DocumentView} bindings={bindings} fieldKey={${fieldStr}} isSelected={isSelected} select={select} isTopMost={isTopMost} />`; } + @computed get field(): FieldValue { const { doc, fieldKey } = this.props; diff --git a/src/client/views/nodes/FormattedTextBox.scss b/src/client/views/nodes/FormattedTextBox.scss index 5139d5d6b..872a2138b 100644 --- a/src/client/views/nodes/FormattedTextBox.scss +++ b/src/client/views/nodes/FormattedTextBox.scss @@ -1,7 +1,7 @@ .ProseMirror { - margin-top: -1em; width: 100%; - height: 100%; + height: auto; + min-height: 100% } .ProseMirror:focus { diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 16728d471..c0969a8c3 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -10,8 +10,6 @@ import "./FormattedTextBox.scss"; import React = require("react") import { RichTextField } from "../../../fields/RichTextField"; import { FieldViewProps, FieldView } from "./FieldView"; -import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView"; -import { observer } from "mobx-react"; // FormattedTextBox: Displays an editable plain text node that maps to a specified Key of a Document @@ -32,7 +30,7 @@ import { observer } from "mobx-react"; //] export class FormattedTextBox extends React.Component { - public static LayoutString() { return FieldView.LayoutString(FormattedTextBox) } + public static LayoutString(fieldStr: string = "DataKey") { return FieldView.LayoutString(FormattedTextBox, fieldStr) } private _ref: React.RefObject; private _editorView: Opt; private _reactionDisposer: Opt; @@ -118,6 +116,7 @@ export class FormattedTextBox extends React.Component { style={{ color: "initial", whiteSpace: "initial", + height: "auto" }} onPointerDown={this.onPointerDown} ref={this._ref} />) diff --git a/src/client/views/nodes/ImageBox.scss b/src/client/views/nodes/ImageBox.scss index 36f5e0fe0..5b15b3329 100644 --- a/src/client/views/nodes/ImageBox.scss +++ b/src/client/views/nodes/ImageBox.scss @@ -1,7 +1,8 @@ .imageBox-cont { padding: 0vw; - position: absolute; + position: relative; + text-align: center; width: 100%; max-width: 100%; max-height: 100% diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts index 6d6c6a546..42e3f6b58 100644 --- a/src/fields/KeyStore.ts +++ b/src/fields/KeyStore.ts @@ -22,5 +22,6 @@ export namespace KeyStore { export const LayoutKeys = new Key("LayoutKeys"); export const LayoutFields = new Key("LayoutFields"); export const ColumnsKey = new Key("SchemaColumns"); + export const Caption = new Key("Caption"); export const ActiveFrame = new Key("ActiveFrame"); } -- cgit v1.2.3-70-g09d2 From 9663623dbe9f54bd3f233c8de7cb9f112f17a7cc Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Sat, 23 Feb 2019 04:49:48 -0500 Subject: Added web clippings on drag and drop --- src/client/documents/Documents.ts | 24 +++++++++++++++++++++ .../views/collections/CollectionFreeFormView.tsx | 3 ++- .../views/collections/CollectionViewBase.tsx | 9 ++++++++ src/client/views/nodes/DocumentView.tsx | 3 ++- src/client/views/nodes/FieldView.tsx | 4 ++++ src/client/views/nodes/WebView.tsx | 22 +++++++++++++++++++ src/fields/HtmlField.ts | 25 ++++++++++++++++++++++ src/fields/KeyStore.ts | 1 + src/fields/TextField.ts | 2 +- src/server/Message.ts | 2 +- src/server/ServerUtil.ts | 6 +++++- 11 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 src/client/views/nodes/WebView.tsx create mode 100644 src/fields/HtmlField.ts (limited to 'src/fields/KeyStore.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 6ec5aa711..d8e1db0b0 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -9,6 +9,8 @@ import { ImageField } from "../../fields/ImageField"; import { ImageBox } from "../views/nodes/ImageBox"; import { CollectionView, CollectionViewType } from "../views/collections/CollectionView"; import { FieldView } from "../views/nodes/FieldView"; +import { HtmlField } from "../../fields/HtmlField"; +import { WebView } from "../views/nodes/WebView"; export interface DocumentOptions { x?: number; @@ -79,6 +81,28 @@ export namespace Documents { return doc; } + let htmlProto: Document; + const htmlProtoId = "htmlProto"; + function GetHtmlPrototype(): Document { + if (!htmlProto) { + htmlProto = new Document(htmlProtoId); + htmlProto.Set(KeyStore.X, new NumberField(0)); + htmlProto.Set(KeyStore.Y, new NumberField(0)); + htmlProto.Set(KeyStore.Width, new NumberField(300)); + htmlProto.Set(KeyStore.Height, new NumberField(150)); + htmlProto.Set(KeyStore.Layout, new TextField(WebView.LayoutString())); + htmlProto.Set(KeyStore.LayoutKeys, new ListField([KeyStore.Data])); + } + return htmlProto; + } + + export function HtmlDocument(html: string, options: DocumentOptions = {}): Document { + let doc = GetHtmlPrototype().MakeDelegate(); + setupOptions(doc, options); + doc.Set(KeyStore.Data, new HtmlField(html)); + return doc; + } + let imageProto: Document; const imageProtoId = "imageProto"; function GetImagePrototype(): Document { diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 4799eda97..b031c35a7 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -13,6 +13,7 @@ import { CollectionSchemaView } from "../collections/CollectionSchemaView"; import { CollectionView } from "../collections/CollectionView"; import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; import { DocumentView } from "../nodes/DocumentView"; +import { WebView } from "../nodes/WebView"; import { FormattedTextBox } from "../nodes/FormattedTextBox"; import { ImageBox } from "../nodes/ImageBox"; import "./CollectionFreeFormView.scss"; @@ -185,7 +186,7 @@ export class CollectionFreeFormView extends CollectionViewBase { get backgroundView() { return !this.backgroundLayout ? (null) : ( e.preventDefault() let that = this; + let html = e.dataTransfer.getData("text/html"); + let text = e.dataTransfer.getData("text/plain"); + if (html) { + let htmlDoc = Documents.HtmlDocument(html, { ...options }); + htmlDoc.SetText(KeyStore.DocumentText, text); + this.props.addDocument(htmlDoc); + return; + } + for (let i = 0; i < e.dataTransfer.items.length; i++) { let item = e.dataTransfer.items[i]; if (item.kind === "string" && item.type.indexOf("uri") != -1) { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index a9e211431..ad1328e5d 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -12,6 +12,7 @@ import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionFreeFormView } from "../collections/CollectionFreeFormView"; import { CollectionSchemaView } from "../collections/CollectionSchemaView"; import { CollectionView, CollectionViewType } from "../collections/CollectionView"; +import { WebView } from "./WebView"; import { ContextMenu } from "../ContextMenu"; import { FormattedTextBox } from "../nodes/FormattedTextBox"; import { ImageBox } from "../nodes/ImageBox"; @@ -196,7 +197,7 @@ export class DocumentView extends React.Component { @computed get mainContent() { return { } else if (field instanceof NumberField) { return

{field.Data}

+ } else if (field instanceof HtmlField) { + return } else if (field != FieldWaiting) { return

{field.GetValue}

} else diff --git a/src/client/views/nodes/WebView.tsx b/src/client/views/nodes/WebView.tsx new file mode 100644 index 000000000..717aa8bf5 --- /dev/null +++ b/src/client/views/nodes/WebView.tsx @@ -0,0 +1,22 @@ +import { FieldViewProps, FieldView } from "./FieldView"; +import { computed } from "mobx"; +import { observer } from "mobx-react"; +import { KeyStore } from "../../../fields/KeyStore"; +import React = require('react') +import { TextField } from "../../../fields/TextField"; +import { HtmlField } from "../../../fields/HtmlField"; +import { RichTextField } from "../../../fields/RichTextField"; + +@observer +export class WebView extends React.Component { + public static LayoutString(fieldStr: string = "DataKey") { return FieldView.LayoutString(WebView, fieldStr) } + + @computed + get html(): string { + return this.props.doc.GetData(KeyStore.Data, HtmlField, "" as string); + } + + render() { + return + } +} \ No newline at end of file diff --git a/src/fields/HtmlField.ts b/src/fields/HtmlField.ts new file mode 100644 index 000000000..a07326095 --- /dev/null +++ b/src/fields/HtmlField.ts @@ -0,0 +1,25 @@ +import { BasicField } from "./BasicField"; +import { Types } from "../server/Message"; +import { FieldId } from "./Field"; + +export class HtmlField extends BasicField { + constructor(data: string = "", id?: FieldId, save: boolean = true) { + super(data, save, id); + } + + ToScriptString(): string { + return `new HtmlField("${this.Data}")`; + } + + Copy() { + return new HtmlField(this.Data); + } + + ToJson(): { _id: string; type: Types; data: any; } { + return { + type: Types.Html, + data: this.Data, + _id: this.Id, + } + } +} \ No newline at end of file diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts index 42e3f6b58..290fa2be7 100644 --- a/src/fields/KeyStore.ts +++ b/src/fields/KeyStore.ts @@ -24,4 +24,5 @@ export namespace KeyStore { export const ColumnsKey = new Key("SchemaColumns"); export const Caption = new Key("Caption"); export const ActiveFrame = new Key("ActiveFrame"); + export const DocumentText = new Key("DocumentText"); } diff --git a/src/fields/TextField.ts b/src/fields/TextField.ts index ad96ab6d9..71d8ea310 100644 --- a/src/fields/TextField.ts +++ b/src/fields/TextField.ts @@ -22,4 +22,4 @@ export class TextField extends BasicField { _id: this.Id } } -} +} \ No newline at end of file diff --git a/src/server/Message.ts b/src/server/Message.ts index 7f3190f7f..80fc9a80d 100644 --- a/src/server/Message.ts +++ b/src/server/Message.ts @@ -45,7 +45,7 @@ export class GetFieldArgs { } export enum Types { - Number, List, Key, Image, Document, Text, RichText, DocumentReference + Number, List, Key, Image, Document, Text, RichText, DocumentReference, Html } export class DocumentTransfer implements Transferable { diff --git a/src/server/ServerUtil.ts b/src/server/ServerUtil.ts index 46c409ec4..08e72fdae 100644 --- a/src/server/ServerUtil.ts +++ b/src/server/ServerUtil.ts @@ -9,6 +9,7 @@ import { Document } from './../fields/Document'; import { Server } from './../client/Server'; import { Types } from './Message'; import { Utils } from '../Utils'; +import { HtmlField } from '../fields/HtmlField'; export class ServerUtils { public static FromJson(json: any): Field { @@ -27,6 +28,8 @@ export class ServerUtils { return new NumberField(data, id, false) case Types.Text: return new TextField(data, id, false) + case Types.Html: + return new HtmlField(data, id, false) case Types.RichText: return new RichTextField(data, id, false) case Types.Key: @@ -42,7 +45,8 @@ export class ServerUtils { doc._proxies.set(element[0], element[1]); }); return doc + default: + throw Error("Error, unrecognized field type received from server. If you just created a new field type, be sure to add it here"); } - return new TextField(data, id) } } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From cdcfa6efa54a79b304cdcb2ffb084451116aeaac Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sat, 23 Feb 2019 10:12:39 -0500 Subject: added an overlay layer to collections... but it blocks events. not sure how to fix. --- src/client/documents/Documents.ts | 7 +++++++ .../views/collections/CollectionFreeFormView.tsx | 24 ++++++++++++++++++++++ src/fields/KeyStore.ts | 1 + 3 files changed, 32 insertions(+) (limited to 'src/fields/KeyStore.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 6ec5aa711..e0d44e535 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -112,6 +112,12 @@ export namespace Documents { + FormattedTextBox.LayoutString("CaptionKey") + `
` }; + function OverlayLayoutString() { + return `
+
` + + FormattedTextBox.LayoutString("CaptionKey") + + `
+
` }; export function ImageDocument(url: string, options: DocumentOptions = {}): Document { let doc = GetImagePrototype().MakeDelegate(); @@ -119,6 +125,7 @@ export namespace Documents { doc.Set(KeyStore.Data, new ImageField(new URL(url))); doc.Set(KeyStore.Caption, new TextField("my caption...")); doc.Set(KeyStore.BackgroundLayout, new TextField(CaptionLayoutString())); + //doc.Set(KeyStore.OverlayLayout, new TextField(OverlayLayoutString())); doc.Set(KeyStore.LayoutKeys, new ListField([KeyStore.Data, KeyStore.Annotations, KeyStore.Caption])); let annotation = Documents.TextDocument({ title: "hello" }); diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 4799eda97..ee0f3730d 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -161,6 +161,12 @@ export class CollectionFreeFormView extends CollectionViewBase { return field.Data; } } + @computed get overlayLayout(): string | undefined { + let field = this.props.Document.GetT(KeyStore.OverlayLayout, TextField); + if (field && field !== "") { + return field.Data; + } + } @computed get views() { const { fieldKey, Document } = this.props; @@ -192,6 +198,17 @@ export class CollectionFreeFormView extends CollectionViewBase { onError={(test: any) => console.log(test)} />); } + @computed + get overlayView() { + return !this.overlayLayout ? (null) : + ( console.log(test)} + />); + } getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-COLLECTION_BORDER_WIDTH, -COLLECTION_BORDER_WIDTH).transform(this.getLocalTransform()) getLocalTransform = (): Transform => Transform.Identity.translate(-this.panX, -this.panY).scale(1 / this.scale); noScaling = () => 1; @@ -199,6 +216,12 @@ export class CollectionFreeFormView extends CollectionViewBase { render() { const panx: number = this.props.Document.GetNumber(KeyStore.PanX, 0); const pany: number = this.props.Document.GetNumber(KeyStore.PanY, 0); + var overlay = this.overlayView ? +
+ {this.overlayView} +
+ : + (null); return (
+ {overlay}
); } diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts index 42e3f6b58..78ed09efd 100644 --- a/src/fields/KeyStore.ts +++ b/src/fields/KeyStore.ts @@ -19,6 +19,7 @@ export namespace KeyStore { export const ViewType = new Key("ViewType"); export const Layout = new Key("Layout"); export const BackgroundLayout = new Key("BackgroundLayout"); + export const OverlayLayout = new Key("OverlayLayout"); export const LayoutKeys = new Key("LayoutKeys"); export const LayoutFields = new Key("LayoutFields"); export const ColumnsKey = new Key("SchemaColumns"); -- cgit v1.2.3-70-g09d2