aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes')
-rw-r--r--src/client/views/nodes/AnnotationView.tsx12
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx79
-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.tsx154
-rw-r--r--src/client/views/nodes/FormattedTextBox.scss2
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx3
-rw-r--r--src/client/views/nodes/ImageBox.scss9
-rw-r--r--src/client/views/nodes/ImageBox.tsx4
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>)
}