diff options
author | bob <bcz@cs.brown.edu> | 2019-02-04 18:10:27 -0500 |
---|---|---|
committer | bob <bcz@cs.brown.edu> | 2019-02-04 18:10:27 -0500 |
commit | 00a4534c535281aaecf4b47da64f1a0770e3bf68 (patch) | |
tree | ba26deb79349ccc472da4fa9c7bc85ec36dc1250 | |
parent | e79e53d78546501fc855b76a84f000289ed7433a (diff) |
not working
-rw-r--r-- | src/Main.tsx | 27 | ||||
-rw-r--r-- | src/documents/Documents.ts | 3 | ||||
-rw-r--r-- | src/views/collections/CollectionDockingView.tsx | 20 | ||||
-rw-r--r-- | src/views/collections/CollectionFreeFormView.tsx | 37 | ||||
-rw-r--r-- | src/views/collections/CollectionSchemaView.tsx | 16 | ||||
-rw-r--r-- | src/views/nodes/DocumentView.tsx | 188 | ||||
-rw-r--r-- | src/views/nodes/FieldTextBox.tsx | 3 | ||||
-rw-r--r-- | src/views/nodes/FieldView.tsx | 4 | ||||
-rw-r--r-- | src/views/nodes/ImageBox.tsx | 5 |
9 files changed, 154 insertions, 149 deletions
diff --git a/src/Main.tsx b/src/Main.tsx index 431a5db96..cbdf0ae98 100644 --- a/src/Main.tsx +++ b/src/Main.tsx @@ -1,18 +1,17 @@ +import { action, configure } from 'mobx'; +import "normalize.css"; import * as React from 'react'; import * as ReactDOM from 'react-dom'; -import "./Main.scss"; -import "normalize.css" -import { Key, KeyStore as KS, KeyStore } from './fields/Key'; -import { NumberField } from './fields/NumberField'; -import { Document } from './fields/Document'; -import { configure, runInAction, action } from 'mobx'; -import { Documents } from './documents/Documents'; import { DocumentDecorations } from './DocumentDecorations'; -import { CollectionFreeFormView } from './views/collections/CollectionFreeFormView'; +import { Documents } from './documents/Documents'; +import { Document } from './fields/Document'; +import { KeyStore, KeyStore as KS } from './fields/Key'; import { ListField } from './fields/ListField'; -import { DocumentView } from './views/nodes/DocumentView'; -import { ContextMenu } from './views/ContextMenu'; +import { NumberField } from './fields/NumberField'; import { TextField } from './fields/TextField'; +import "./Main.scss"; +import { ContextMenu } from './views/ContextMenu'; +import { DocumentView, DocumentContentsView } from './views/nodes/DocumentView'; configure({ enforceActions: "observed" @@ -52,7 +51,7 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) { schemaDocs[4].SetFieldValue(KS.Author, "Bob", TextField); schemaDocs.push(doc2); const doc7 = Documents.SchemaDocument(schemaDocs) - const docset = [doc1, doc2, doc3, doc7]; + const docset = [doc3];//[doc1, doc2, doc3, doc7]; let doc4 = Documents.CollectionDocument(docset, { x: 0, y: 400, title: "mini collection" }); @@ -71,17 +70,17 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) { // mainNodes.Data.push(doc2); mainNodes.Data.push(doc4); // mainNodes.Data.push(doc3); - mainNodes.Data.push(doc5); + //mainNodes.Data.push(doc5); // mainNodes.Data.push(doc1); //mainNodes.Data.push(doc2); - mainNodes.Data.push(doc6); + //mainNodes.Data.push(doc6); mainContainer.SetField(KeyStore.Data, mainNodes); } //); ReactDOM.render(( <div style={{ position: "absolute", width: "100%", height: "100%" }}> - <DocumentView Document={mainContainer} ContainingCollectionView={undefined} ContainingDocumentView={undefined} /> + <DocumentContentsView Document={mainContainer} ContainingCollectionView={undefined} ContainingDocumentContentsView={undefined} /> <DocumentDecorations /> <ContextMenu /> </div>), diff --git a/src/documents/Documents.ts b/src/documents/Documents.ts index 932abf7bc..29ef32966 100644 --- a/src/documents/Documents.ts +++ b/src/documents/Documents.ts @@ -9,6 +9,7 @@ import { CollectionSchemaView } from "../views/collections/CollectionSchemaView" import { ImageField } from "../fields/ImageField"; import { RichTextField } from "../fields/RichTextField"; import { ImageBox } from "../views/nodes/ImageBox"; +import { CollectionFreeFormView } from "../views/collections/CollectionFreeFormView"; interface DocumentOptions { x?: number; @@ -138,7 +139,7 @@ export namespace Documents { collectionProto.SetField(KeyStore.PanY, new NumberField(0)); collectionProto.SetField(KeyStore.Width, new NumberField(300)); collectionProto.SetField(KeyStore.Height, new NumberField(300)); - collectionProto.SetField(KeyStore.Layout, new TextField('<CollectionFreeFormView Document={Document} fieldKey={DataKey} ContainingDocumentView={ContainingDocumentView}/>')); + collectionProto.SetField(KeyStore.Layout, new TextField(CollectionFreeFormView.LayoutString())); collectionProto.SetField(KeyStore.LayoutKeys, new ListField([KeyStore.Data])); } return collectionProto; diff --git a/src/views/collections/CollectionDockingView.tsx b/src/views/collections/CollectionDockingView.tsx index 177e3510a..197b7df46 100644 --- a/src/views/collections/CollectionDockingView.tsx +++ b/src/views/collections/CollectionDockingView.tsx @@ -4,7 +4,7 @@ import React = require("react"); import FlexLayout from "flexlayout-react"; import { action, observable, computed } from "mobx"; import { Document } from "../../fields/Document"; -import { DocumentView } from "../nodes/DocumentView"; +import { DocumentView, DocumentContentsView } from "../nodes/DocumentView"; import { ListField } from "../../fields/ListField"; import { NumberField } from "../../fields/NumberField"; import { SSL_OP_SINGLE_DH_USE } from "constants"; @@ -20,11 +20,11 @@ import { CollectionViewBase, CollectionViewProps, COLLECTION_BORDER_WIDTH } from export class CollectionDockingView extends CollectionViewBase { private static UseGoldenLayout = true; - public static LayoutString() { return '<CollectionDockingView Document={Document} fieldKey={DataKey} ContainingDocumentView={ContainingDocumentView}/>'; } + public static LayoutString() { return '<CollectionDockingView DocumentForCollection={Document} CollectionFieldKey={DataKey} DocumentContentsContainingCollection={ContainingDocumentContentsView}/>'; } private _containerRef = React.createRef<HTMLDivElement>(); @computed private get modelForFlexLayout() { - const { fieldKey, Document: Document } = this.props; + const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; const value: Document[] = Document.GetFieldValue(fieldKey, ListField, []); var docs = value.map(doc => { return { type: 'tabset', weight: 50, selected: 0, children: [{ type: "tab", name: doc.Title, component: doc.Id }] }; @@ -40,7 +40,7 @@ export class CollectionDockingView extends CollectionViewBase { } @computed private get modelForGoldenLayout(): any { - const { fieldKey, Document: Document } = this.props; + const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; const value: Document[] = Document.GetFieldValue(fieldKey, ListField, []); var docs = value.map(doc => { return { type: 'component', componentName: 'documentViewComponent', componentState: { doc: doc } }; @@ -69,7 +69,7 @@ export class CollectionDockingView extends CollectionViewBase { @action onResize = (event: any) => { - var cur = this.props.ContainingDocumentView!.MainContent.current; + var cur = this.props.DocumentContentsContainingCollection!.MainContent.current; // bcz: since GoldenLayout isn't a React component itself, we need to notify it to resize when its document container's size has changed CollectionDockingView.myLayout.updateSize(cur!.getBoundingClientRect().width, cur!.getBoundingClientRect().height); @@ -92,11 +92,11 @@ export class CollectionDockingView extends CollectionViewBase { if (component === "button") { return <button>{node.getName()}</button>; } - const { fieldKey, Document: Document } = this.props; + const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; const value: Document[] = Document.GetFieldValue(fieldKey, ListField, []); for (var i: number = 0; i < value.length; i++) { if (value[i].Id === component) { - return (<DocumentView key={value[i].Id} ContainingCollectionView={this} Document={value[i]} ContainingDocumentView={this.props.ContainingDocumentView} />); + return (<DocumentView key={value[i].Id} ContainingCollectionView={this} Document={value[i]} ContainingDocumentContentsView={this.props.DocumentContentsContainingCollection} />); } } if (component === "text") { @@ -237,7 +237,7 @@ export class CollectionDockingView extends CollectionViewBase { container.getElement().html("<div id='" + containingDiv + "'></div>"); setTimeout(function () { ReactDOM.render(( - <DocumentView key={state.doc.Id} Document={state.doc} ContainingCollectionView={me} ContainingDocumentView={me.props.ContainingDocumentView} /> + <DocumentContentsView key={state.doc.Id} Document={state.doc} ContainingCollectionView={me} ContainingDocumentContentsView={me.props.DocumentContentsContainingCollection} /> // bcz: need to fill in containingdoccontnents with value of DocumentContents when created... ), document.getElementById(containingDiv) ); @@ -252,10 +252,10 @@ export class CollectionDockingView extends CollectionViewBase { render() { - const { fieldKey, Document: Document } = this.props; + const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; const value: Document[] = Document.GetFieldValue(fieldKey, ListField, []); // bcz: not sure why, but I need these to force the flexlayout to update when the collection size changes. - var s = this.props.ContainingDocumentView!.ScalingToScreenSpace; + var s = this.props.DocumentContentsContainingCollection != undefined ? this.props.DocumentContentsContainingCollection!.ScalingToScreenSpace : 1; var w = Document.GetFieldValue(KeyStore.Width, NumberField, Number(0)) / s; var h = Document.GetFieldValue(KeyStore.Height, NumberField, Number(0)) / s; diff --git a/src/views/collections/CollectionFreeFormView.tsx b/src/views/collections/CollectionFreeFormView.tsx index ab2aeee64..d0dea7a79 100644 --- a/src/views/collections/CollectionFreeFormView.tsx +++ b/src/views/collections/CollectionFreeFormView.tsx @@ -15,6 +15,7 @@ import { CollectionViewBase, CollectionViewProps, COLLECTION_BORDER_WIDTH } from @observer export class CollectionFreeFormView extends CollectionViewBase { + public static LayoutString() { return '<CollectionFreeFormView DocumentForCollection={Document} CollectionFieldKey={DataKey} DocumentContentsContainingCollection={ContainingDocumentContentsView}/>'; } private _containerRef = React.createRef<HTMLDivElement>(); private _canvasRef = React.createRef<HTMLDivElement>(); private _nodeContainerRef = React.createRef<HTMLDivElement>(); @@ -36,14 +37,14 @@ export class CollectionFreeFormView extends CollectionViewBase { const xOffset = de.data["xOffset"] as number || 0; const yOffset = de.data["yOffset"] as number || 0; const { scale, translateX, translateY } = Utils.GetScreenTransform(this._canvasRef.current!); - let sscale = this.props.ContainingDocumentView!.props.Document.GetFieldValue(KeyStore.Scale, NumberField, Number(1)) + let sscale = this.props.DocumentContentsContainingCollection!.props.Document.GetFieldValue(KeyStore.Scale, NumberField, Number(1)) const screenX = de.x - xOffset; const screenY = de.y - yOffset; const docX = (screenX - translateX) / sscale / scale; const docY = (screenY - translateY) / sscale / scale; doc.x = docX; doc.y = docY; - this.bringToFront(doc); + //this.bringToFront(doc); } e.stopPropagation(); } @@ -82,11 +83,11 @@ export class CollectionFreeFormView extends CollectionViewBase { if (!e.cancelBubble) { e.preventDefault(); e.stopPropagation(); - let currScale: number = this.props.ContainingDocumentView!.ScalingToScreenSpace; - let x = this.props.Document.GetFieldValue(KeyStore.PanX, NumberField, Number(0)); - let y = this.props.Document.GetFieldValue(KeyStore.PanY, NumberField, Number(0)); - this.props.Document.SetFieldValue(KeyStore.PanX, x + (e.pageX - this._lastX) / currScale, NumberField); - this.props.Document.SetFieldValue(KeyStore.PanY, y + (e.pageY - this._lastY) / currScale, NumberField); + let currScale: number = this.props.DocumentContentsContainingCollection!.ScalingToScreenSpace; + let x = this.props.DocumentForCollection.GetFieldValue(KeyStore.PanX, NumberField, Number(0)); + let y = this.props.DocumentForCollection.GetFieldValue(KeyStore.PanY, NumberField, Number(0)); + this.props.DocumentForCollection.SetFieldValue(KeyStore.PanX, x + (e.pageX - this._lastX) / currScale, NumberField); + this.props.DocumentForCollection.SetFieldValue(KeyStore.PanY, y + (e.pageY - this._lastY) / currScale, NumberField); this._lastX = e.pageX; this._lastY = e.pageY; } @@ -96,7 +97,7 @@ export class CollectionFreeFormView extends CollectionViewBase { onPointerWheel = (e: React.WheelEvent): void => { e.stopPropagation(); - let { LocalX, Ss, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY } = this.props.ContainingDocumentView!.TransformToLocalPoint(e.pageX, e.pageY); + let { LocalX, Ss, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY } = this.props.DocumentContentsContainingCollection!.TransformToLocalPoint(e.pageX, e.pageY); var deltaScale = (1 - (e.deltaY / 1000)) * Ss; @@ -106,9 +107,9 @@ export class CollectionFreeFormView extends CollectionViewBase { let dx = ContainerX - newContainerX; let dy = ContainerY - newContainerY; - this.props.Document.SetField(KeyStore.Scale, new NumberField(deltaScale)); - this.props.Document.SetFieldValue(KeyStore.PanX, Panxx + dx, NumberField); - this.props.Document.SetFieldValue(KeyStore.PanY, Panyy + dy, NumberField); + this.props.DocumentForCollection.SetField(KeyStore.Scale, new NumberField(deltaScale)); + this.props.DocumentForCollection.SetFieldValue(KeyStore.PanX, Panxx + dx, NumberField); + this.props.DocumentForCollection.SetFieldValue(KeyStore.PanY, Panyy + dy, NumberField); } @action @@ -118,8 +119,8 @@ export class CollectionFreeFormView extends CollectionViewBase { let fReader = new FileReader() let file = e.dataTransfer.items[0].getAsFile(); let that = this; - const panx: number = this.props.Document.GetFieldValue(KeyStore.PanX, NumberField, Number(0)); - const pany: number = this.props.Document.GetFieldValue(KeyStore.PanY, NumberField, Number(0)); + const panx: number = this.props.DocumentForCollection.GetFieldValue(KeyStore.PanX, NumberField, Number(0)); + const pany: number = this.props.DocumentForCollection.GetFieldValue(KeyStore.PanY, NumberField, Number(0)); let x = e.pageX - panx let y = e.pageY - pany @@ -129,10 +130,10 @@ export class CollectionFreeFormView extends CollectionViewBase { let doc = Documents.ImageDocument(url, { x: x, y: y }) - let docs = that.props.Document.GetFieldT(KeyStore.Data, ListField); + let docs = that.props.DocumentForCollection.GetFieldT(KeyStore.Data, ListField); if (!docs) { docs = new ListField<Document>(); - that.props.Document.SetField(KeyStore.Data, docs) + that.props.DocumentForCollection.SetField(KeyStore.Data, docs) } docs.Data.push(doc); } @@ -148,7 +149,7 @@ export class CollectionFreeFormView extends CollectionViewBase { @action bringToFront(doc: DocumentView) { - const { fieldKey, Document: Document } = this.props; + const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; const value: Document[] = Document.GetListField<Document>(fieldKey, []); var topmost = value.reduce((topmost, d) => Math.max(d.GetNumberField(KeyStore.ZIndex, 0), topmost), -1000); @@ -165,7 +166,7 @@ export class CollectionFreeFormView extends CollectionViewBase { } render() { - const { fieldKey, Document: Document } = this.props; + const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; const value: Document[] = Document.GetListField<Document>(fieldKey, []); const panx: number = Document.GetNumberField(KeyStore.PanX, 0); const pany: number = Document.GetNumberField(KeyStore.PanY, 0); @@ -186,7 +187,7 @@ export class CollectionFreeFormView extends CollectionViewBase { <div className="node-container" ref={this._nodeContainerRef}> {value.map(doc => { - return (<DocumentView key={doc.Id} ContainingCollectionView={this} Document={doc} ContainingDocumentView={this.props.ContainingDocumentView} />); + return (<DocumentView key={doc.Id} ContainingCollectionView={this} Document={doc} ContainingDocumentContentsView={this.props.DocumentContentsContainingCollection} />); })} </div> </div> diff --git a/src/views/collections/CollectionSchemaView.tsx b/src/views/collections/CollectionSchemaView.tsx index 420a68cc9..f625b39c5 100644 --- a/src/views/collections/CollectionSchemaView.tsx +++ b/src/views/collections/CollectionSchemaView.tsx @@ -1,4 +1,4 @@ -import { DocumentContents } from "../nodes/DocumentView"; +import { DocumentContentsView } from "../nodes/DocumentView"; import React = require("react") import ReactTable, { ReactTableDefaults, CellInfo, ComponentPropsGetterRC, ComponentPropsGetterR } from "react-table"; import { observer } from "mobx-react"; @@ -14,19 +14,19 @@ import { CollectionViewBase } from "./CollectionViewBase"; @observer export class CollectionSchemaView extends CollectionViewBase { - public static LayoutString() { return '<CollectionSchemaView Document={Document} fieldKey={DataKey} ContainingDocumentView={ContainingDocumentView}/>'; } + public static LayoutString() { return '<CollectionSchemaView DocumentForCollection={Document} CollectionFieldKey={DataKey} ContainingDocumentView={ContainingDocumentContentsView}/>'; } @observable selectedIndex = 0; renderCell = (rowProps: CellInfo) => { - if (!this.props.ContainingDocumentView) { + if (!this.props.DocumentContentsContainingCollection) { return <div></div> } let props: FieldViewProps = { doc: rowProps.value[0], fieldKey: rowProps.value[1], - documentViewContainer: this.props.ContainingDocumentView + documentViewContainer: this.props.DocumentContentsContainingCollection } return ( <FieldView {...props} /> @@ -71,15 +71,15 @@ export class CollectionSchemaView extends CollectionViewBase { } render() { - const { Document, fieldKey } = this.props; + const { DocumentForCollection: Document, CollectionFieldKey: fieldKey } = this.props; const children = Document.GetListField<Document>(fieldKey, []); const columns = Document.GetListField(KS.ColumnsKey, [KS.Title, KS.Data, KS.Author]) let content; if (this.selectedIndex != -1) { - content = (<DocumentContents Document={children[this.selectedIndex]} - ContainingDocumentView={this.props.ContainingDocumentView} - ContainingCollectionView={undefined} />) + content = (<DocumentContentsView Document={children[this.selectedIndex]} + ContainingDocumentContentsView={this.props.DocumentContentsContainingCollection} + ContainingCollectionView={this} />) } else { content = <div /> } diff --git a/src/views/nodes/DocumentView.tsx b/src/views/nodes/DocumentView.tsx index dd47d4455..3cc0f3bf6 100644 --- a/src/views/nodes/DocumentView.tsx +++ b/src/views/nodes/DocumentView.tsx @@ -6,29 +6,33 @@ import { Key, KeyStore } from "../../fields/Key"; import { ListField } from "../../fields/ListField"; import { NumberField } from "../../fields/NumberField"; import { TextField } from "../../fields/TextField"; -import { CollectionSchemaView } from "../collections/CollectionSchemaView" -import "./NodeView.scss" import { DragManager } from "../../util/DragManager"; import { SelectionManager } from "../../util/SelectionManager"; import { Utils } from "../../Utils"; -import { CollectionViewBase, COLLECTION_BORDER_WIDTH } from "../collections/CollectionViewBase"; import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionFreeFormView } from "../collections/CollectionFreeFormView"; +import { CollectionSchemaView } from "../collections/CollectionSchemaView"; +import { CollectionViewBase, COLLECTION_BORDER_WIDTH } from "../collections/CollectionViewBase"; import { ContextMenu } from "../ContextMenu"; import { FieldTextBox } from "../nodes/FieldTextBox"; import { ImageBox } from "../nodes/ImageBox"; import "./NodeView.scss"; import React = require("react"); +import { baseKeymap } from "prosemirror-commands"; const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this? interface DocumentViewProps { Document: Document; ContainingCollectionView: Opt<CollectionViewBase>; - ContainingDocumentView: Opt<DocumentView>; + ContainingDocumentContentsView: Opt<DocumentContentsView>; } @observer -export class DocumentContents extends React.Component<DocumentViewProps> { +export class DocumentContentsView extends React.Component<DocumentViewProps> { + protected _mainCont = React.createRef<any>(); + get MainContent() { + return this._mainCont; + } @computed get layout(): string { return this.props.Document.GetFieldValue(KeyStore.Layout, TextField, String("<p>Error loading layout data</p>")); @@ -43,12 +47,92 @@ export class DocumentContents extends React.Component<DocumentViewProps> { get layoutFields(): Key[] { return this.props.Document.GetFieldValue(KeyStore.LayoutFields, ListField, new Array<Key>()); } + + // + // returns the cumulative scaling between the document and the screen + // + @computed + public get ScalingToScreenSpace(): number { + if (this.props.ContainingDocumentContentsView != undefined) { + let ss = this.props.ContainingDocumentContentsView.props.Document.GetFieldValue(KeyStore.Scale, NumberField, Number(1)); + return this.props.ContainingDocumentContentsView.ScalingToScreenSpace * ss; + } + return 1; + } + + // + // Converts a coordinate in the screen space of the app into a local document coordinate. + // + public TransformToLocalPoint(screenX: number, screenY: number) { + // if this collection view is nested within another collection view, then + // first transform the screen point into the parent collection's coordinate space. + let { LocalX: parentX, LocalY: parentY } = this.props.ContainingDocumentContentsView != undefined ? + this.props.ContainingDocumentContentsView!.TransformToLocalPoint(screenX, screenY) : + { LocalX: screenX, LocalY: screenY }; + let ContainerX: number = parentX - COLLECTION_BORDER_WIDTH; + let ContainerY: number = parentY - COLLECTION_BORDER_WIDTH; + + var Xx = this.props.Document.GetFieldValue(KeyStore.X, NumberField, Number(0)); + var Yy = this.props.Document.GetFieldValue(KeyStore.Y, NumberField, Number(0)); + // CollectionDockingViews change the location of their children frames without using a Dash transformation. + // They also ignore any transformation that may have been applied to their content document. + // NOTE: this currently assumes CollectionDockingViews aren't nested. + if (this.props.ContainingCollectionView instanceof CollectionDockingView) { + var { translateX: rx, translateY: ry } = Utils.GetScreenTransform(this.MainContent.current!); + Xx = rx - COLLECTION_BORDER_WIDTH; + Yy = ry - COLLECTION_BORDER_WIDTH; + } + + let Ss = this.props.Document.GetFieldValue(KeyStore.Scale, NumberField, Number(1)); + let Panxx = this.props.Document.GetFieldValue(KeyStore.PanX, NumberField, Number(0)); + let Panyy = this.props.Document.GetFieldValue(KeyStore.PanY, NumberField, Number(0)); + let LocalX = (ContainerX - (Xx + Panxx)) / Ss; + let LocalY = (ContainerY - (Yy + Panyy)) / Ss; + + return { LocalX, Ss, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY }; + } + + // + // Converts a point in the coordinate space of a document to a screen space coordinate. + // + public TransformToScreenPoint(localX: number, localY: number, Ss: number = 1, Panxx: number = 0, Panyy: number = 0): { ScreenX: number, ScreenY: number } { + + var Xx = this.props.Document.GetFieldValue(KeyStore.X, NumberField, Number(0)); + var Yy = this.props.Document.GetFieldValue(KeyStore.Y, NumberField, Number(0)); + // CollectionDockingViews change the location of their children frames without using a Dash transformation. + // They also ignore any transformation that may have been applied to their content document. + // NOTE: this currently assumes CollectionDockingViews aren't nested. + if (this.props.ContainingCollectionView instanceof CollectionDockingView) { + var { translateX: rx, translateY: ry } = Utils.GetScreenTransform(this.MainContent.current!); + Xx = rx - COLLECTION_BORDER_WIDTH; + Yy = ry - COLLECTION_BORDER_WIDTH; + } + + let W = COLLECTION_BORDER_WIDTH; + let H = COLLECTION_BORDER_WIDTH; + let parentX = (localX - W) * Ss + (Xx + Panxx) + W; + let parentY = (localY - H) * Ss + (Yy + Panyy) + H; + + // if this collection view is nested within another collection view, then + // first transform the local point into the parent collection's coordinate space. + let containingDocView = this.props.ContainingDocumentContentsView; + if (containingDocView != undefined) { + let ss = containingDocView.props.Document.GetFieldValue(KeyStore.Scale, NumberField, Number(1)); + let panxx = containingDocView.props.Document.GetFieldValue(KeyStore.PanX, NumberField, Number(0)) + COLLECTION_BORDER_WIDTH * ss; + let panyy = containingDocView.props.Document.GetFieldValue(KeyStore.PanY, NumberField, Number(0)) + COLLECTION_BORDER_WIDTH * ss; + let { ScreenX, ScreenY } = containingDocView.TransformToScreenPoint(parentX, parentY, ss, panxx, panyy); + parentX = ScreenX; + parentY = ScreenY; + } + return { ScreenX: parentX, ScreenY: parentY }; + } render() { let doc = this.props.Document; let bindings = { ...this.props } as any; for (const key of this.layoutKeys) { bindings[key.Name + "Key"] = key; } + bindings.ContainingDocumentContentsView = this; for (const key of this.layoutFields) { let field = doc.GetField(key); if (field) { @@ -56,20 +140,21 @@ export class DocumentContents extends React.Component<DocumentViewProps> { } } return ( - <JsxParser + //<div ref={this._mainCont}> + <JsxParser ref={this._mainCont} components={{ FieldTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }} bindings={bindings} jsx={this.layout} showWarnings={true} onError={(test: any) => { console.log(test) }} /> + //</div> ) } } @observer -export class DocumentView extends React.Component<DocumentViewProps> { - private _mainCont = React.createRef<HTMLDivElement>(); +export class DocumentView extends DocumentContentsView { private _contextMenuCanOpen = false; private _downX: number = 0; private _downY: number = 0; @@ -84,10 +169,6 @@ export class DocumentView extends React.Component<DocumentViewProps> { return new DOMRect(); } - get MainContent() { - return this._mainCont; - } - @computed get x(): number { return this.props.Document.GetFieldValue(KeyStore.X, NumberField, Number(0)); @@ -152,86 +233,6 @@ export class DocumentView extends React.Component<DocumentViewProps> { return this.props.ContainingCollectionView == undefined || this.props.ContainingCollectionView instanceof CollectionDockingView; } - - // - // returns the cumulative scaling between the document and the screen - // - @computed - public get ScalingToScreenSpace(): number { - if (this.props.ContainingDocumentView != undefined) { - let ss = this.props.ContainingDocumentView.props.Document.GetFieldValue(KeyStore.Scale, NumberField, Number(1)); - return this.props.ContainingDocumentView.ScalingToScreenSpace * ss; - } - return 1; - } - - // - // Converts a coordinate in the screen space of the app into a local document coordinate. - // - public TransformToLocalPoint(screenX: number, screenY: number) { - // if this collection view is nested within another collection view, then - // first transform the screen point into the parent collection's coordinate space. - let { LocalX: parentX, LocalY: parentY } = this.props.ContainingDocumentView != undefined ? - this.props.ContainingDocumentView!.TransformToLocalPoint(screenX, screenY) : - { LocalX: screenX, LocalY: screenY }; - let ContainerX: number = parentX - COLLECTION_BORDER_WIDTH; - let ContainerY: number = parentY - COLLECTION_BORDER_WIDTH; - - var Xx = this.props.Document.GetFieldValue(KeyStore.X, NumberField, Number(0)); - var Yy = this.props.Document.GetFieldValue(KeyStore.Y, NumberField, Number(0)); - // CollectionDockingViews change the location of their children frames without using a Dash transformation. - // They also ignore any transformation that may have been applied to their content document. - // NOTE: this currently assumes CollectionDockingViews aren't nested. - if (this.props.ContainingCollectionView instanceof CollectionDockingView) { - var { translateX: rx, translateY: ry } = Utils.GetScreenTransform(this._mainCont.current!); - Xx = rx - COLLECTION_BORDER_WIDTH; - Yy = ry - COLLECTION_BORDER_WIDTH; - } - - let Ss = this.props.Document.GetFieldValue(KeyStore.Scale, NumberField, Number(1)); - let Panxx = this.props.Document.GetFieldValue(KeyStore.PanX, NumberField, Number(0)); - let Panyy = this.props.Document.GetFieldValue(KeyStore.PanY, NumberField, Number(0)); - let LocalX = (ContainerX - (Xx + Panxx)) / Ss; - let LocalY = (ContainerY - (Yy + Panyy)) / Ss; - - return { LocalX, Ss, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY }; - } - - // - // Converts a point in the coordinate space of a document to a screen space coordinate. - // - public TransformToScreenPoint(localX: number, localY: number, Ss: number = 1, Panxx: number = 0, Panyy: number = 0): { ScreenX: number, ScreenY: number } { - - var Xx = this.props.Document.GetFieldValue(KeyStore.X, NumberField, Number(0)); - var Yy = this.props.Document.GetFieldValue(KeyStore.Y, NumberField, Number(0)); - // CollectionDockingViews change the location of their children frames without using a Dash transformation. - // They also ignore any transformation that may have been applied to their content document. - // NOTE: this currently assumes CollectionDockingViews aren't nested. - if (this.props.ContainingCollectionView instanceof CollectionDockingView) { - var { translateX: rx, translateY: ry } = Utils.GetScreenTransform(this._mainCont.current!); - Xx = rx - COLLECTION_BORDER_WIDTH; - Yy = ry - COLLECTION_BORDER_WIDTH; - } - - let W = COLLECTION_BORDER_WIDTH; - let H = COLLECTION_BORDER_WIDTH; - let parentX = (localX - W) * Ss + (Xx + Panxx) + W; - let parentY = (localY - H) * Ss + (Yy + Panyy) + H; - - // if this collection view is nested within another collection view, then - // first transform the local point into the parent collection's coordinate space. - let containingDocView = this.props.ContainingDocumentView; - if (containingDocView != undefined) { - let ss = containingDocView.props.Document.GetFieldValue(KeyStore.Scale, NumberField, Number(1)); - let panxx = containingDocView.props.Document.GetFieldValue(KeyStore.PanX, NumberField, Number(0)) + COLLECTION_BORDER_WIDTH * ss; - let panyy = containingDocView.props.Document.GetFieldValue(KeyStore.PanY, NumberField, Number(0)) + COLLECTION_BORDER_WIDTH * ss; - let { ScreenX, ScreenY } = containingDocView.TransformToScreenPoint(parentX, parentY, ss, panxx, panyy); - parentX = ScreenX; - parentY = ScreenY; - } - return { ScreenX: parentX, ScreenY: parentY }; - } - onPointerDown = (e: React.PointerEvent): void => { this._downX = e.clientX; this._downY = e.clientY; @@ -354,7 +355,8 @@ export class DocumentView extends React.Component<DocumentViewProps> { }} onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown}> - <DocumentContents {...this.props} ContainingDocumentView={this} /> + + <DocumentContentsView {...this.props} /> </div> ); } diff --git a/src/views/nodes/FieldTextBox.tsx b/src/views/nodes/FieldTextBox.tsx index 188b39a17..0a8706517 100644 --- a/src/views/nodes/FieldTextBox.tsx +++ b/src/views/nodes/FieldTextBox.tsx @@ -13,6 +13,7 @@ import "./FieldTextBox.scss"; import React = require("react") import { RichTextField } from "../../fields/RichTextField"; import { FieldViewProps } from "./FieldView"; +import { DocumentView } from "./DocumentView"; // FieldTextBox: Displays an editable plain text node that maps to a specified Key of a Document @@ -110,7 +111,7 @@ export class FieldTextBox extends React.Component<FieldViewProps> { } onPointerDown = (e: React.PointerEvent): void => { let me = this; - if (e.buttons === 1 && SelectionManager.IsSelected(me.props.documentViewContainer)) { + if (e.buttons === 1 && me.props.documentViewContainer instanceof DocumentView && SelectionManager.IsSelected(me.props.documentViewContainer)) { e.stopPropagation(); } } diff --git a/src/views/nodes/FieldView.tsx b/src/views/nodes/FieldView.tsx index 6c1cd956b..b7a1d0526 100644 --- a/src/views/nodes/FieldView.tsx +++ b/src/views/nodes/FieldView.tsx @@ -1,5 +1,5 @@ import React = require("react") -import { DocumentView } from "./DocumentView"; +import { DocumentView, DocumentContentsView } from "./DocumentView"; import { Document } from "../../fields/Document"; import { observer } from "mobx-react"; import { computed } from "mobx"; @@ -20,7 +20,7 @@ import { Key } from "../../fields/Key"; export interface FieldViewProps { fieldKey: Key; doc: Document; - documentViewContainer: DocumentView + documentViewContainer: DocumentContentsView } @observer diff --git a/src/views/nodes/ImageBox.tsx b/src/views/nodes/ImageBox.tsx index 5137dbf38..d2f567423 100644 --- a/src/views/nodes/ImageBox.tsx +++ b/src/views/nodes/ImageBox.tsx @@ -6,6 +6,7 @@ import "./ImageBox.scss"; import React = require("react") import { ImageField } from '../../fields/ImageField'; import { FieldViewProps } from './FieldView'; +import { DocumentView } from './DocumentView'; interface ImageBoxState { photoIndex: number, @@ -38,7 +39,7 @@ export class ImageBox extends React.Component<FieldViewProps, ImageBoxState> { onPointerDown = (e: React.PointerEvent): void => { if (Date.now() - this._lastTap < 300) { - if (e.buttons === 1 && SelectionManager.IsSelected(this.props.documentViewContainer)) { + if (e.buttons === 1 && this.props.documentViewContainer instanceof DocumentView && SelectionManager.IsSelected(this.props.documentViewContainer)) { e.stopPropagation(); this._downX = e.clientX; this._downY = e.clientY; @@ -66,7 +67,7 @@ export class ImageBox extends React.Component<FieldViewProps, ImageBoxState> { const images = [path,]; var lightbox = () => { const { photoIndex } = this.state; - if (this.state.isOpen && SelectionManager.IsSelected(this.props.documentViewContainer)) { + if (this.state.isOpen && this.props.documentViewContainer instanceof DocumentView && SelectionManager.IsSelected(this.props.documentViewContainer)) { return (<Lightbox mainSrc={images[photoIndex]} nextSrc={photoIndex + 1 < images.length ? images[(photoIndex + 1) % images.length] : undefined} |