diff options
Diffstat (limited to 'src/client/views/nodes')
| -rw-r--r-- | src/client/views/nodes/AnnotationView.tsx | 12 | ||||
| -rw-r--r-- | src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 79 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentView.scss (renamed from src/client/views/nodes/NodeView.scss) | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 154 | ||||
| -rw-r--r-- | src/client/views/nodes/FormattedTextBox.scss | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/FormattedTextBox.tsx | 3 | ||||
| -rw-r--r-- | src/client/views/nodes/ImageBox.scss | 9 | ||||
| -rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 4 |
8 files changed, 148 insertions, 117 deletions
diff --git a/src/client/views/nodes/AnnotationView.tsx b/src/client/views/nodes/AnnotationView.tsx deleted file mode 100644 index 2e50370a1..000000000 --- a/src/client/views/nodes/AnnotationView.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import React = require('react') -import { CollectionViewProps } from '../collections/CollectionViewBase'; - -export class AnnotationView extends React.Component<CollectionViewProps> { - - render() { - return ( - <></> - ); - } - -}
\ No newline at end of file diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index bb8dea53b..a2fbe96d2 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -7,10 +7,10 @@ import { SelectionManager } from "../../util/SelectionManager"; import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionFreeFormView } from "../collections/CollectionFreeFormView"; import { ContextMenu } from "../ContextMenu"; -import "./NodeView.scss"; +import "./DocumentView.scss"; import React = require("react"); import { DocumentView, DocumentViewProps } from "./DocumentView"; -var FontAwesomeIcon = require('react-fontawesome'); +import { Transform } from "../../util/Transform"; @observer @@ -18,7 +18,7 @@ export class CollectionFreeFormDocumentView extends DocumentView { private _contextMenuCanOpen = false; private _downX: number = 0; private _downY: number = 0; - //determines whether the blinking cursor for indicating whether a text will be made on key down is visible + // private _mainCont = React.createRef<HTMLDivElement>(); constructor(props: DocumentViewProps) { super(props); @@ -30,50 +30,55 @@ export class CollectionFreeFormDocumentView extends DocumentView { return new DOMRect(); } - @computed - get x(): number { - return this.props.Document.GetData(KeyStore.X, NumberField, Number(0)); + public LeftCorner(): number { + return this.props.Document.GetNumber(KeyStore.X, 0) + super.LeftCorner(); } - @computed - get y(): number { - return this.props.Document.GetData(KeyStore.Y, NumberField, Number(0)); - } - - set x(x: number) { - this.props.Document.SetData(KeyStore.X, x, NumberField) - } - - set y(y: number) { - this.props.Document.SetData(KeyStore.Y, y, NumberField) + public TopCorner(): number { + return this.props.Document.GetNumber(KeyStore.Y, 0) + super.TopCorner(); } @computed get transform(): string { - return `scale(${this.props.Scaling}, ${this.props.Scaling}) translate(${this.x}px, ${this.y}px)`; + return `scale(${this.props.ParentScaling}, ${this.props.ParentScaling}) translate(${this.props.Document.GetNumber(KeyStore.X, 0)}px, ${this.props.Document.GetNumber(KeyStore.Y, 0)}px)`; } @computed get width(): number { - return this.props.Document.GetData(KeyStore.Width, NumberField, Number(0)); + return this.props.Document.GetNumber(KeyStore.Width, 0); + } + + @computed + get nativeWidth(): number { + return this.props.Document.GetNumber(KeyStore.NativeWidth, 0); } set width(w: number) { this.props.Document.SetData(KeyStore.Width, w, NumberField) + if (this.nativeWidth > 0 && this.nativeHeight > 0) { + this.props.Document.SetNumber(KeyStore.Height, this.nativeHeight / this.nativeWidth * w) + } } @computed get height(): number { - return this.props.Document.GetData(KeyStore.Height, NumberField, Number(0)); + return this.props.Document.GetNumber(KeyStore.Height, 0); + } + @computed + get nativeHeight(): number { + return this.props.Document.GetNumber(KeyStore.NativeHeight, 0); } set height(h: number) { - this.props.Document.SetData(KeyStore.Height, h, NumberField) + this.props.Document.SetData(KeyStore.Height, h, NumberField); + if (this.nativeWidth > 0 && this.nativeHeight > 0) { + this.props.Document.SetNumber(KeyStore.Width, this.nativeWidth / this.nativeHeight * h) + } } @computed get zIndex(): number { - return this.props.Document.GetData(KeyStore.ZIndex, NumberField, Number(0)); + return this.props.Document.GetNumber(KeyStore.ZIndex, 0); } set zIndex(h: number) { @@ -205,22 +210,26 @@ export class CollectionFreeFormDocumentView extends DocumentView { } } - render() { - var freestyling = this.props.ContainingCollectionView instanceof CollectionFreeFormView; + getTransform = (): Transform => { + return this.props.GetTransform().translated(this.props.Document.GetNumber(KeyStore.X, 0), this.props.Document.GetNumber(KeyStore.Y, 0)); + } + render() { + var parentScaling = this.nativeWidth > 0 ? this.width / this.nativeWidth : 1; return ( - <div className="node" ref={this._mainCont} style={{ - transformOrigin: "left top", - transform: freestyling ? this.transform : "", - width: freestyling ? this.width : "100%", - height: freestyling ? this.height : "100%", - position: freestyling ? "absolute" : "relative", - zIndex: freestyling ? this.zIndex : 0, - }} + <div className="documentView-node" ref={this._mainCont} onContextMenu={this.onContextMenu} - onPointerDown={this.onPointerDown}> - - <DocumentView {...this.props} DocumentView={this} /> + onPointerDown={this.onPointerDown} + style={{ + transformOrigin: "left top", + transform: this.transform, + width: this.width, + height: this.height, + position: "absolute", + zIndex: this.zIndex, + }}> + + <DocumentView {...this.props} ref={this._renderDoc} ParentScaling={parentScaling} GetTransform={this.getTransform} DocumentView={this} /> </div> ); } diff --git a/src/client/views/nodes/NodeView.scss b/src/client/views/nodes/DocumentView.scss index dac1c0a8e..8e2ebd690 100644 --- a/src/client/views/nodes/NodeView.scss +++ b/src/client/views/nodes/DocumentView.scss @@ -1,4 +1,4 @@ -.node { +.documentView-node { position: absolute; background: #cdcdcd; overflow: hidden; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index bba5becc3..c5270e0cd 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -4,8 +4,6 @@ import { Document } from "../../../fields/Document"; import { Opt, FieldWaiting } from "../../../fields/Field"; import { Key, KeyStore } from "../../../fields/Key"; import { ListField } from "../../../fields/ListField"; -import { NumberField } from "../../../fields/NumberField"; -import { TextField } from "../../../fields/TextField"; import { Utils } from "../../../Utils"; import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionFreeFormView } from "../collections/CollectionFreeFormView"; @@ -13,31 +11,44 @@ import { CollectionSchemaView } from "../collections/CollectionSchemaView"; import { CollectionViewBase, COLLECTION_BORDER_WIDTH } from "../collections/CollectionViewBase"; import { FormattedTextBox } from "../nodes/FormattedTextBox"; import { ImageBox } from "../nodes/ImageBox"; -import "./NodeView.scss"; +import "./DocumentView.scss"; import React = require("react"); +import { Transform } from "../../util/Transform"; const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this? export interface DocumentViewProps { - Document: Document; DocumentView: Opt<DocumentView> // needed only to set ContainingDocumentView on CollectionViewProps when invoked from JsxParser -- is there a better way? ContainingCollectionView: Opt<CollectionViewBase>; - Scaling: number; + + Document: Document; + AddDocument?: (doc: Document) => void; + RemoveDocument?: (doc: Document) => boolean; + GetTransform: () => Transform; + ParentScaling: number; } + @observer export class DocumentView extends React.Component<DocumentViewProps> { + protected _renderDoc = React.createRef<any>(); protected _mainCont = React.createRef<any>(); get MainContent() { return this._mainCont; } + + @computed + get parentScaling(): number { + return this._renderDoc.current ? this._renderDoc.current.props.ParentScaling : this.props.ParentScaling > 0 ? this.props.ParentScaling : 1; + } + @computed get layout(): string { - return this.props.Document.GetData(KeyStore.Layout, TextField, String("<p>Error loading layout data</p>")); + return this.props.Document.GetText(KeyStore.Layout, "<p>Error loading layout data</p>"); } @computed - get annotatedlayout(): string { - return this.props.Document.GetData(KeyStore.AnnotatedLayout, TextField, String("<p>Error loading layout data</p>")); + get backgroundLayout(): string { + return this.props.Document.GetText(KeyStore.BackgroundLayout, ""); } @computed @@ -63,75 +74,78 @@ export class DocumentView extends React.Component<DocumentViewProps> { return 1; } + + public LeftCorner(): number { + if (this.props.ContainingCollectionView) { + if (this.props.ContainingCollectionView instanceof CollectionDockingView) { + // this is a hacky way to account for the titles/pane placement/etc of a CollectionDockingView + // this only works if the collectionDockingView is the root collection, too. + // need to find a better way. + var { translateX: rx, translateY: ry } = Utils.GetScreenTransform(this.MainContent.current!); + return rx + COLLECTION_BORDER_WIDTH; + } + return COLLECTION_BORDER_WIDTH; // assumes all collections have the same border + } + return 0; + } + + public TopCorner(): number { + if (this.props.ContainingCollectionView) { + if (this.props.ContainingCollectionView instanceof CollectionDockingView) { + // this is a hacky way to account for the titles/pane placement/etc of a CollectionDockingView + // this only works if the collectionDockingView is the root collection, too. + // need to find a better way. + var { translateX: rx, translateY: ry } = Utils.GetScreenTransform(this.MainContent.current!); + return ry + COLLECTION_BORDER_WIDTH; + } + return COLLECTION_BORDER_WIDTH; // assumes all collections have the same border + } + return 0; + } // - // Converts a coordinate in the screen space of the app into a local document coordinate. + // Converts a coordinate in the screen space of the app to a local point in the space of the DocumentView. + // This also returns the point in the coordinate space of this document's containing CollectionView // 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.ContainingCollectionView != undefined && - this.props.ContainingCollectionView.props.ContainingDocumentView != undefined ? - this.props.ContainingCollectionView.props.ContainingDocumentView.TransformToLocalPoint(screenX, screenY) : - { LocalX: screenX, LocalY: screenY }; + let containingCollectionViewDoc = this.props.ContainingCollectionView ? this.props.ContainingCollectionView.props.ContainingDocumentView : undefined; + let { LocalX: parentX, LocalY: parentY } = !containingCollectionViewDoc ? { LocalX: screenX, LocalY: screenY } : + containingCollectionViewDoc.TransformToLocalPoint(screenX, screenY); let ContainerX: number = parentX - COLLECTION_BORDER_WIDTH; let ContainerY: number = parentY - COLLECTION_BORDER_WIDTH; - var Xx = this.props.Document.GetData(KeyStore.X, NumberField, Number(0)); - var Yy = this.props.Document.GetData(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.GetNumber(KeyStore.Scale, 1); - let Panxx = this.props.Document.GetData(KeyStore.PanX, NumberField, Number(0)); - let Panyy = this.props.Document.GetData(KeyStore.PanY, NumberField, Number(0)); - let LocalX = (ContainerX - (Xx + Panxx)) / Ss; - let LocalY = (ContainerY - (Yy + Panyy)) / Ss; + let Panxx = this.props.Document.GetNumber(KeyStore.PanX, 0); + let Panyy = this.props.Document.GetNumber(KeyStore.PanY, 0); + let LocalX = (ContainerX - (this.LeftCorner() + Panxx)) / Ss; + let LocalY = (ContainerY - (this.TopCorner() + Panyy)) / Ss; - return { LocalX, Ss, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY }; + return { LocalX, LocalY, ContainerX, ContainerY }; } // - // Converts a point in the coordinate space of a document to a screen space coordinate. + // Converts a point in the coordinate space of the document to coordinate in app screen coordinates // - public TransformToScreenPoint(localX: number, localY: number, Ss: number = 1, Panxx: number = 0, Panyy: number = 0): { ScreenX: number, ScreenY: number } { - - var Xx = this.props.Document.GetData(KeyStore.X, NumberField, Number(0)); - var Yy = this.props.Document.GetData(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; - + public TransformToScreenPoint(localX: number, localY: number, applyViewXf: boolean = false): { ScreenX: number, ScreenY: number } { + var parentScaling = applyViewXf ? this.parentScaling : 1; + let Panxx = applyViewXf ? this.props.Document.GetNumber(KeyStore.PanX, 0) : 0; + let Panyy = applyViewXf ? this.props.Document.GetNumber(KeyStore.PanY, 0) : 0; + var Zoom = applyViewXf ? this.props.Document.GetNumber(KeyStore.Scale, 1) : 1; + + let parentX = this.LeftCorner() + (Panxx + (localX - COLLECTION_BORDER_WIDTH) * Zoom) * parentScaling; + let parentY = this.TopCorner() + (Panyy + (localY - COLLECTION_BORDER_WIDTH) * Zoom) * parentScaling; // 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.ContainingCollectionView != undefined ? this.props.ContainingCollectionView.props.ContainingDocumentView : undefined; - if (containingDocView != undefined) { - let ss = containingDocView.props.Document.GetNumber(KeyStore.Scale, 1) * this.props.Scaling; - let panxx = containingDocView.props.Document.GetData(KeyStore.PanX, NumberField, Number(0)) + COLLECTION_BORDER_WIDTH * ss; - let panyy = containingDocView.props.Document.GetData(KeyStore.PanY, NumberField, Number(0)) + COLLECTION_BORDER_WIDTH * ss; - let { ScreenX, ScreenY } = containingDocView.TransformToScreenPoint(parentX, parentY, ss, panxx, panyy); + let containingDocView = this.props.ContainingCollectionView ? this.props.ContainingCollectionView.props.ContainingDocumentView : undefined; + if (containingDocView) { + let { ScreenX, ScreenY } = containingDocView.TransformToScreenPoint(parentX + COLLECTION_BORDER_WIDTH * parentScaling, parentY + COLLECTION_BORDER_WIDTH * parentScaling, true); parentX = ScreenX; parentY = ScreenY; } return { ScreenX: parentX, ScreenY: parentY }; } - render() { let bindings = { ...this.props } as any; for (const key of this.layoutKeys) { @@ -144,16 +158,28 @@ export class DocumentView extends React.Component<DocumentViewProps> { if (bindings.DocumentView === undefined) { bindings.DocumentView = this; // set the DocumentView to this if it hasn't already been set by a sub-class during its render method. } - var annotated = <JsxParser - components={{ FormattedTextBox: FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }} - bindings={bindings} - jsx={this.annotatedlayout} - showWarnings={true} - onError={(test: any) => { console.log(test) }} - />; - bindings["BackgroundView"] = this.annotatedlayout ? annotated : null; + if (this.backgroundLayout) { + var backgroundview = <JsxParser + components={{ FormattedTextBox: FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }} + bindings={bindings} + jsx={this.backgroundLayout} + showWarnings={true} + onError={(test: any) => { console.log(test) }} + />; + bindings["BackgroundView"] = backgroundview; + } + var nativewidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 0); + var nativeheight = this.props.Document.GetNumber(KeyStore.NativeHeight, 0); + var width = nativewidth > 0 ? nativewidth + "px" : "100%"; + var height = nativeheight > 0 ? nativeheight + "px" : "100%"; return ( - <div className="node" ref={this._mainCont} style={{ width: "100%", height: "100%", }}> + <div className="documentView-node" ref={this._mainCont} + style={{ + width: width, + height: height, + transformOrigin: "top left", + transform: `scale(${this.props.ParentScaling},${this.props.ParentScaling})` + }}> <JsxParser components={{ FormattedTextBox: FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }} bindings={bindings} diff --git a/src/client/views/nodes/FormattedTextBox.scss b/src/client/views/nodes/FormattedTextBox.scss index 492367fce..5139d5d6b 100644 --- a/src/client/views/nodes/FormattedTextBox.scss +++ b/src/client/views/nodes/FormattedTextBox.scss @@ -9,6 +9,6 @@ } .formattedTextBox-cont { - background: white; + background: beige; padding: 1vw; }
\ No newline at end of file diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index eead43b9f..f6bd0c0f8 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -12,6 +12,7 @@ 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 @@ -117,7 +118,7 @@ export class FormattedTextBox extends React.Component<FieldViewProps> { return (<div className="formattedTextBox-cont" style={{ color: "initial", - whiteSpace: "initial" + whiteSpace: "initial", }} onPointerDown={this.onPointerDown} ref={this._ref} />) diff --git a/src/client/views/nodes/ImageBox.scss b/src/client/views/nodes/ImageBox.scss index 83392311b..36f5e0fe0 100644 --- a/src/client/views/nodes/ImageBox.scss +++ b/src/client/views/nodes/ImageBox.scss @@ -1,7 +1,14 @@ .imageBox-cont { padding: 0vw; - position: absolute + position: absolute; + width: 100%; + max-width: 100%; + max-height: 100% +} +.imageBox-cont img { + max-width: 100%; + max-height: 100% } .imageBox-button { diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index b96e717ed..2fa70734d 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -85,11 +85,11 @@ export class ImageBox extends React.Component<FieldViewProps> { let field = this.props.doc.Get(this.props.fieldKey); let path = field == FieldWaiting ? "https://image.flaticon.com/icons/svg/66/66163.svg" : field instanceof ImageField ? field.Data.href : "http://www.cs.brown.edu/~bcz/face.gif"; - let width = this.props.doc.GetNumber(KeyStore.Width, 1); + let nativeWidth = this.props.doc.GetNumber(KeyStore.NativeWidth, 1); return ( <div className="imageBox-cont" onPointerDown={this.onPointerDown} ref={this._ref} > - <img src={path} width={width} alt="Image not found" /> + <img src={path} width={nativeWidth} alt="Image not found" /> {this.lightbox(path)} </div>) } |
