aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/util/DragManager.ts12
-rw-r--r--src/client/util/SelectionManager.ts12
-rw-r--r--src/client/util/Transform.ts73
-rw-r--r--src/client/views/DocumentDecorations.tsx43
-rw-r--r--src/client/views/Main.tsx11
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx20
-rw-r--r--src/client/views/collections/CollectionFreeFormView.tsx70
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx8
-rw-r--r--src/client/views/collections/CollectionViewBase.tsx16
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx167
-rw-r--r--src/client/views/nodes/DocumentView.tsx267
-rw-r--r--src/client/views/nodes/FieldView.tsx6
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx2
-rw-r--r--src/client/views/nodes/ImageBox.tsx4
14 files changed, 353 insertions, 358 deletions
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index f4dcce7c8..337ec855a 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -78,9 +78,13 @@ export namespace DragManager {
dragElement.style.transformOrigin = "0 0";
dragElement.style.zIndex = "1000";
dragElement.style.transform = `translate(${x}px, ${y}px) scale(${scaleX}, ${scaleY})`;
+ dragElement.style.width = `${rect.width / scaleX}px`;
+ dragElement.style.height = `${rect.height / scaleY}px`;
+ // It seems like the above code should be able to just be this:
+ // dragElement.style.transform = `translate(${x}px, ${y}px)`;
+ // dragElement.style.width = `${rect.width}px`;
+ // dragElement.style.height = `${rect.height}px`;
dragDiv.appendChild(dragElement);
- _lastPointerX = dragData["xOffset"] + rect.left;
- _lastPointerY = dragData["yOffset"] + rect.top;
let hideSource = false;
if (typeof options.hideSource === "boolean") {
@@ -96,8 +100,8 @@ export namespace DragManager {
const moveHandler = (e: PointerEvent) => {
e.stopPropagation();
e.preventDefault();
- x += e.clientX - _lastPointerX; _lastPointerX = e.clientX;
- y += e.clientY - _lastPointerY; _lastPointerY = e.clientY;
+ x += e.movementX;
+ y += e.movementY;
dragElement.style.transform = `translate(${x}px, ${y}px) scale(${scaleX}, ${scaleY})`;
};
const upHandler = (e: PointerEvent) => {
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 0759ae110..1a711ae64 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -1,13 +1,13 @@
-import { CollectionFreeFormDocumentView } from "../views/nodes/CollectionFreeFormDocumentView";
import { observable, action } from "mobx";
+import { DocumentView } from "../views/nodes/DocumentView";
export namespace SelectionManager {
class Manager {
@observable
- SelectedDocuments: Array<CollectionFreeFormDocumentView> = [];
+ SelectedDocuments: Array<DocumentView> = [];
@action
- SelectDoc(doc: CollectionFreeFormDocumentView, ctrlPressed: boolean): void {
+ SelectDoc(doc: DocumentView, ctrlPressed: boolean): void {
// if doc is not in SelectedDocuments, add it
if (!ctrlPressed) {
manager.SelectedDocuments = [];
@@ -21,11 +21,11 @@ export namespace SelectionManager {
const manager = new Manager;
- export function SelectDoc(doc: CollectionFreeFormDocumentView, ctrlPressed: boolean): void {
+ export function SelectDoc(doc: DocumentView, ctrlPressed: boolean): void {
manager.SelectDoc(doc, ctrlPressed)
}
- export function IsSelected(doc: CollectionFreeFormDocumentView): boolean {
+ export function IsSelected(doc: DocumentView): boolean {
return manager.SelectedDocuments.indexOf(doc) !== -1;
}
@@ -33,7 +33,7 @@ export namespace SelectionManager {
manager.SelectedDocuments = []
}
- export function SelectedDocuments(): Array<CollectionFreeFormDocumentView> {
+ export function SelectedDocuments(): Array<DocumentView> {
return manager.SelectedDocuments;
}
} \ No newline at end of file
diff --git a/src/client/util/Transform.ts b/src/client/util/Transform.ts
index 7861ed308..9fd4f7bef 100644
--- a/src/client/util/Transform.ts
+++ b/src/client/util/Transform.ts
@@ -7,6 +7,10 @@ export class Transform {
return new Transform(0, 0, 1);
}
+ get TranslateX(): number { return this._translateX; }
+ get TranslateY(): number { return this._translateY; }
+ get Scale(): number { return this._scale; }
+
constructor(x: number, y: number, scale: number) {
this._translateX = x;
this._translateY = y;
@@ -19,56 +23,67 @@ export class Transform {
return this;
}
- translated = (x: number, y: number): Transform => {
- return this.copy().translate(x, y);
- }
-
- preTranslate = (x: number, y: number): Transform => {
- this._translateX += x * this._scale;
- this._translateY += y * this._scale;
+ scale = (scale: number): Transform => {
+ this._scale *= scale;
+ this._translateX *= scale;
+ this._translateY *= scale;
return this;
}
- preTranslated = (x: number, y: number): Transform => {
- return this.copy().preTranslate(x, y);
+ scaleAbout = (scale: number, x: number, y: number): Transform => {
+ this._translateX += x * this._scale - x * this._scale * scale;
+ this._translateY += y * this._scale - y * this._scale * scale;
+ this._scale *= scale;
+ return this;
}
- scale = (scale: number): Transform => {
- this._scale *= scale;
+ transform = (transform: Transform): Transform => {
+ this._translateX = transform._translateX + transform._scale * this._translateX;
+ this._translateY = transform._translateY + transform._scale * this._translateY;
+ this._scale *= transform._scale;
return this;
}
- scaled = (scale: number): Transform => {
- return this.copy().scale(scale);
+ preTranslate = (x: number, y: number): Transform => {
+ this._translateX += this._scale * x;
+ this._translateY += this._scale * y;
+ return this;
}
preScale = (scale: number): Transform => {
this._scale *= scale;
- this._translateX *= scale;
- this._translateY *= scale;
return this;
}
- preScaled = (scale: number): Transform => {
- return this.copy().preScale(scale);
- }
-
- transform = (transform: Transform): Transform => {
+ preTransform = (transform: Transform): Transform => {
this._translateX += transform._translateX * this._scale;
this._translateY += transform._translateY * this._scale;
this._scale *= transform._scale;
return this;
}
- transformed = (transform: Transform): Transform => {
- return this.copy().transform(transform);
+ translated = (x: number, y: number): Transform => {
+ return this.copy().translate(x, y);
}
- preTransform = (transform: Transform): Transform => {
- this._translateX = transform._translateX + this._translateX * transform._scale;
- this._translateY = transform._translateY + this._translateY * transform._scale;
- this._scale *= transform._scale;
- return this;
+ preTranslated = (x: number, y: number): Transform => {
+ return this.copy().preTranslate(x, y);
+ }
+
+ scaled = (scale: number): Transform => {
+ return this.copy().scale(scale);
+ }
+
+ scaledAbout = (scale: number, x: number, y: number): Transform => {
+ return this.copy().scaleAbout(scale, x, y);
+ }
+
+ preScaled = (scale: number): Transform => {
+ return this.copy().preScale(scale);
+ }
+
+ transformed = (transform: Transform): Transform => {
+ return this.copy().transform(transform);
}
preTransformed = (transform: Transform): Transform => {
@@ -83,6 +98,10 @@ export class Transform {
return [x, y];
}
+ transformDirection = (x: number, y: number): [number, number] => {
+ return [x * this._scale, y * this._scale];
+ }
+
inverse = () => {
return new Transform(-this._translateX / this._scale, -this._translateY / this._scale, 1 / this._scale)
}
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 1224495f6..d385bcdef 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -5,6 +5,7 @@ import { observer } from "mobx-react";
import './DocumentDecorations.scss'
import { CollectionFreeFormView } from "./collections/CollectionFreeFormView";
import { KeyStore } from '../../fields/Key'
+import { NumberField } from "../../fields/NumberField";
@observer
export class DocumentDecorations extends React.Component {
@@ -26,11 +27,15 @@ export class DocumentDecorations extends React.Component {
!(element.props.ContainingCollectionView instanceof CollectionFreeFormView)) {
return bounds;
}
- var spt = element.TransformToScreenPoint(0, 0);
- var bpt = element.TransformToScreenPoint(element.width, element.height);
+ let transform = element.props.ScreenToLocalTransform().inverse();
+ var [sptX, sptY] = transform.transformPoint(0, 0);
+ // var [bptX, bptY] = transform.transformDirection(element.width, element.height);
+ let doc = element.props.Document;
+ let [bptX, bptY] = [doc.GetNumber(KeyStore.Width, 0), doc.GetNumber(KeyStore.Height, 0)];
+ [bptX, bptY] = transform.transformPoint(bptX, bptY);
return {
- x: Math.min(spt.ScreenX, bounds.x), y: Math.min(spt.ScreenY, bounds.y),
- r: Math.max(bpt.ScreenX, bounds.r), b: Math.max(bpt.ScreenY, bounds.b)
+ x: Math.min(sptX, bounds.x), y: Math.min(sptY, bounds.y),
+ r: Math.max(bptX, bounds.r), b: Math.max(bptY, bounds.b)
}
}, { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: Number.MIN_VALUE, b: Number.MIN_VALUE });
}
@@ -106,16 +111,32 @@ export class DocumentDecorations extends React.Component {
SelectionManager.SelectedDocuments().forEach(element => {
const rect = element.screenRect;
+ // if (rect.width !== 0) {
+ // let scale = element.width / rect.width;
+ // let actualdW = Math.max(element.width + (dW * scale), 20);
+ // let actualdH = Math.max(element.height + (dH * scale), 20);
+ // element.x += dX * (actualdW - element.width);
+ // element.y += dY * (actualdH - element.height);
+ // if (Math.abs(dW) > Math.abs(dH))
+ // element.width = actualdW;
+ // else
+ // element.height = actualdH;
+ // }
if (rect.width !== 0) {
- let scale = element.width / rect.width;
- let actualdW = Math.max(element.width + (dW * scale), 20);
- let actualdH = Math.max(element.height + (dH * scale), 20);
- element.props.Document.SetNumber(KeyStore.X, element.props.Document.GetNumber(KeyStore.X, 0) + dX * (actualdW - element.width));
- element.props.Document.SetNumber(KeyStore.Y, element.props.Document.GetNumber(KeyStore.Y, 0) + dY * (actualdH - element.height));
+ let doc = element.props.Document;
+ let width = doc.GetOrCreate(KeyStore.Width, NumberField);
+ let height = doc.GetOrCreate(KeyStore.Height, NumberField);
+ let x = doc.GetOrCreate(KeyStore.X, NumberField);
+ let y = doc.GetOrCreate(KeyStore.X, NumberField);
+ let scale = width.Data / rect.width;
+ let actualdW = Math.max(width.Data + (dW * scale), 20);
+ let actualdH = Math.max(height.Data + (dH * scale), 20);
+ x.Data += dX * (actualdW - width.Data);
+ y.Data += dY * (actualdH - height.Data);
if (Math.abs(dW) > Math.abs(dH))
- element.width = actualdW;
+ width.Data = actualdW;
else
- element.height = actualdH;
+ height.Data = actualdH;
}
})
}
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index aec9618ae..1eeec7ff5 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -67,10 +67,7 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) {
let doc6 = Documents.CollectionDocument(docset2, {
x: 350, y: 100, width: 600, height: 600, title: "docking collection"
});
- let mainNodes = null;// mainContainer.GetFieldT(KeyStore.Data, ListField);
- if (!mainNodes) {
- mainNodes = new ListField<Document>();
- }
+ let mainNodes = mainContainer.GetOrCreate<ListField<Document>>(KeyStore.Data, ListField);
// mainNodes.Data.push(doc6);
// mainNodes.Data.push(doc2);
mainNodes.Data.push(doc4);
@@ -79,7 +76,6 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) {
// mainNodes.Data.push(doc1);
// mainNodes.Data.push(doc2);
mainNodes.Data.push(doc6);
- mainContainer.Set(KeyStore.Data, mainNodes);
}
//}
//);
@@ -87,8 +83,9 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) {
ReactDOM.render((
<div style={{ position: "absolute", width: "100%", height: "100%" }}>
<DocumentView Document={mainContainer}
- AddDocument={undefined} RemoveDocument={undefined} GetTransform={() => Transform.Identity}
- ParentScaling={1}
+ AddDocument={undefined} RemoveDocument={undefined} ScreenToLocalTransform={() => Transform.Identity}
+ Scaling={1}
+ isTopMost={true}
ContainingCollectionView={undefined} DocumentView={undefined} />
<DocumentDecorations />
<ContextMenu />
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 1653994cf..1c1f6f8b4 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -15,6 +15,7 @@ import { CollectionViewBase, CollectionViewProps, COLLECTION_BORDER_WIDTH } from
import React = require("react");
import * as ReactDOM from 'react-dom';
import Measure from "react-measure";
+import { Utils } from "../../../Utils";
@observer
export class CollectionDockingView extends CollectionViewBase {
@@ -97,8 +98,9 @@ export class CollectionDockingView extends CollectionViewBase {
if (value[i].Id === component) {
return (<DocumentView key={value[i].Id} Document={value[i]}
AddDocument={this.addDocument} RemoveDocument={this.removeDocument}
- GetTransform={() => Transform.Identity}
- ParentScaling={1}
+ ScreenToLocalTransform={() => Transform.Identity}
+ isTopMost={true}
+ Scaling={1}
ContainingCollectionView={this} DocumentView={undefined} />);
}
}
@@ -238,14 +240,14 @@ export class CollectionDockingView extends CollectionViewBase {
var containingDiv = "component_" + me.nextId();
container.getElement().html("<div id='" + containingDiv + "'></div>");
setTimeout(function () {
- let divContainer = document.getElementById(containingDiv);
+ let divContainer = document.getElementById(containingDiv) as HTMLDivElement;
if (divContainer) {
let props: DockingProps = {
ContainingDiv: containingDiv,
Document: state.doc,
Container: container,
CollectionDockingView: me,
- HtmlElement: divContainer
+ HtmlElement: divContainer,
}
ReactDOM.render((<RenderClass {...props} />), divContainer);
if (CollectionDockingView.myLayout._maxstack) {
@@ -292,7 +294,7 @@ interface DockingProps {
Document: Document,
Container: any,
HtmlElement: HTMLElement,
- CollectionDockingView: CollectionDockingView
+ CollectionDockingView: CollectionDockingView,
}
@observer
export class RenderClass extends React.Component<DockingProps> {
@@ -306,8 +308,12 @@ export class RenderClass extends React.Component<DockingProps> {
<DocumentView key={this.props.Document.Id} Document={this.props.Document}
AddDocument={this.props.CollectionDockingView.addDocument}
RemoveDocument={this.props.CollectionDockingView.removeDocument}
- GetTransform={() => Transform.Identity}
- ParentScaling={this._parentScaling}
+ Scaling={this._parentScaling}
+ ScreenToLocalTransform={() => {
+ let { scale, translateX, translateY } = Utils.GetScreenTransform(this.props.HtmlElement);
+ return this.props.CollectionDockingView.props.ScreenToLocalTransform().translate(-translateX, -translateY).scale(scale)
+ }}
+ isTopMost={true}
ContainingCollectionView={this.props.CollectionDockingView} DocumentView={undefined} />
if (nativeWidth > 0 && (layout.indexOf("CollectionFreeForm") == -1 || layout.indexOf("AnnotationsKey") != -1)) {
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index 04373df12..eca8a0adf 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -14,6 +14,7 @@ import { NumberField } from "../../../fields/NumberField";
import { Documents } from "../../documents/Documents";
import { FieldWaiting } from "../../../fields/Field";
import { Transform } from "../../util/Transform";
+import { DocumentView } from "../nodes/DocumentView";
@observer
export class CollectionFreeFormView extends CollectionViewBase {
@@ -45,23 +46,22 @@ export class CollectionFreeFormView extends CollectionViewBase {
@action
drop = (e: Event, de: DragManager.DropEvent) => {
- const doc = de.data["document"];
+ const doc: DocumentView = de.data["document"];
var me = this;
- if (doc instanceof CollectionFreeFormDocumentView) {
- if (doc.props.ContainingCollectionView && doc.props.ContainingCollectionView !== this) {
- doc.props.ContainingCollectionView.removeDocument(doc.props.Document);
- this.addDocument(doc.props.Document);
- }
- const xOffset = de.data["xOffset"] as number || 0;
- const yOffset = de.data["yOffset"] as number || 0;
- const { translateX, translateY } = Utils.GetScreenTransform(this._canvasRef.current!);
- const currScale = this.resizeScaling * this.zoomScaling * this.props.ContainingDocumentView!.ScalingToScreenSpace;
- const screenX = de.x - xOffset;
- const screenY = de.y - yOffset;
- doc.props.Document.SetNumber(KeyStore.X, (screenX - translateX) / currScale);
- doc.props.Document.SetNumber(KeyStore.Y, (screenY - translateY) / currScale);
- this.bringToFront(doc);
+ if (doc.props.ContainingCollectionView && doc.props.ContainingCollectionView !== this) {
+ doc.props.ContainingCollectionView.removeDocument(doc.props.Document);
+ this.addDocument(doc.props.Document);
}
+ const xOffset = de.data["xOffset"] as number || 0;
+ const yOffset = de.data["yOffset"] as number || 0;
+ //this should be able to use translate and scale methods on an Identity transform, no?
+ const transform = me.getTransform();
+ const screenX = de.x - xOffset;
+ const screenY = de.y - yOffset;
+ const [x, y] = transform.transformPoint(screenX, screenY);
+ doc.props.Document.SetNumber(KeyStore.X, x);
+ doc.props.Document.SetNumber(KeyStore.Y, y);
+ this.bringToFront(doc);
e.stopPropagation();
}
@@ -94,8 +94,8 @@ export class CollectionFreeFormView extends CollectionViewBase {
document.removeEventListener("pointerup", this.onPointerUp);
e.stopPropagation();
if (Math.abs(this._downX - e.clientX) < 3 && Math.abs(this._downY - e.clientY) < 3) {
- if (!SelectionManager.IsSelected(this.props.ContainingDocumentView as CollectionFreeFormDocumentView)) {
- SelectionManager.SelectDoc(this.props.ContainingDocumentView as CollectionFreeFormDocumentView, false);
+ if (!this.props.isSelected()) {
+ this.props.select(false);
}
}
}
@@ -105,11 +105,11 @@ export class CollectionFreeFormView extends CollectionViewBase {
if (!e.cancelBubble && this.active) {
e.preventDefault();
e.stopPropagation();
- let currScale: number = this.props.ContainingDocumentView!.ScalingToScreenSpace;
let x = this.props.DocumentForCollection.GetNumber(KeyStore.PanX, 0);
let y = this.props.DocumentForCollection.GetNumber(KeyStore.PanY, 0);
+ let [dx, dy] = this.props.ScreenToLocalTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
- this.SetPan(x + (e.pageX - this._lastX) / currScale, y + (e.pageY - this._lastY) / currScale);
+ this.SetPan(x + dx, y + dy);
}
this._lastX = e.pageX;
this._lastY = e.pageY;
@@ -123,15 +123,16 @@ export class CollectionFreeFormView extends CollectionViewBase {
let coefficient = 1000;
// if (modes[e.deltaMode] == 'pixels') coefficient = 50;
// else if (modes[e.deltaMode] == 'lines') coefficient = 1000; // This should correspond to line-height??
+ let transform = this.getTransform();
+
+ let deltaScale = (1 - (e.deltaY / coefficient));
+ let [x, y] = transform.transformPoint(e.clientX, e.clientY);
- let { LocalX, LocalY, ContainerX, ContainerY } = this.props.ContainingDocumentView!.TransformToLocalPoint(e.pageX, e.pageY);
- var Xx = this.props.ContainingDocumentView!.LeftCorner();
- var Yy = this.props.ContainingDocumentView!.TopCorner();
- var deltaScale = (1 - (e.deltaY / coefficient)) * this.props.ContainingDocumentView!.props.Document.GetNumber(KeyStore.Scale, 1);
- var newDeltaScale = this.isAnnotationOverlay ? Math.max(1, deltaScale) : deltaScale;
+ let localTransform = this.getLocalTransform();
+ localTransform = localTransform.inverse().scaleAbout(deltaScale, x, y)
- this.props.DocumentForCollection.SetNumber(KeyStore.Scale, newDeltaScale);
- this.SetPan(ContainerX - (LocalX * newDeltaScale + Xx), ContainerY - (LocalY * newDeltaScale + Yy));
+ this.props.DocumentForCollection.SetNumber(KeyStore.Scale, localTransform.Scale);
+ this.SetPan(localTransform.TranslateX, localTransform.TranslateY);
}
@action
@@ -180,7 +181,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
}
@action
- bringToFront(doc: CollectionFreeFormDocumentView) {
+ bringToFront(doc: DocumentView) {
const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props;
const value: Document[] = Document.GetList<Document>(fieldKey, []);
@@ -210,8 +211,12 @@ export class CollectionFreeFormView extends CollectionViewBase {
}
getTransform = (): Transform => {
+ return this.props.ScreenToLocalTransform().translate(-COLLECTION_BORDER_WIDTH, -COLLECTION_BORDER_WIDTH).transform(this.getLocalTransform())
+ }
+
+ getLocalTransform = (): Transform => {
const [x, y] = this.translate;
- return this.props.GetTransform().scaled(this.scale).translate(x, y);
+ return Transform.Identity.translate(-x, -y).scale(1 / this.scale);
}
render() {
@@ -236,14 +241,15 @@ export class CollectionFreeFormView extends CollectionViewBase {
style={{ width: "100%", transformOrigin: "left top", transform: ` translate(${panx}px, ${pany}px) scale(${this.zoomScaling}, ${this.zoomScaling})` }}
ref={this._canvasRef}>
- {this.props.BackgroundView}
+ {this.props.BackgroundView ? this.props.BackgroundView() : null}
{value.map(doc => {
return (<CollectionFreeFormDocumentView key={doc.Id} Document={doc}
AddDocument={this.addDocument}
RemoveDocument={this.removeDocument}
- GetTransform={this.getTransform}
- ParentScaling={1}
- ContainingCollectionView={this} DocumentView={undefined} />);
+ ScreenToLocalTransform={this.getTransform}
+ isTopMost={false}
+ Scaling={1}
+ ContainingCollectionView={this} DocumentView={this.props.ContainingDocumentView} />);
})}
</div>
</div>
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 76706f520..9a0ce0782 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -28,7 +28,8 @@ export class CollectionSchemaView extends CollectionViewBase {
let props: FieldViewProps = {
doc: rowProps.value[0],
fieldKey: rowProps.value[1],
- DocumentViewForField: undefined,
+ isSelected: () => false,
+ isTopMost: false
}
let contents = (
<FieldView {...props} />
@@ -122,8 +123,9 @@ export class CollectionSchemaView extends CollectionViewBase {
<div ref={measureRef}>
<DocumentView Document={children[this.selectedIndex]}
AddDocument={this.addDocument} RemoveDocument={this.removeDocument}
- GetTransform={() => Transform.Identity}//TODO This should probably be an actual transform
- ParentScaling={this._parentScaling}
+ ScreenToLocalTransform={() => Transform.Identity}//TODO This should probably be an actual transform
+ Scaling={this._parentScaling}
+ isTopMost={false}
DocumentView={undefined} ContainingCollectionView={me} />
</div>
}
diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx
index 1cf07ce05..4cbafe950 100644
--- a/src/client/views/collections/CollectionViewBase.tsx
+++ b/src/client/views/collections/CollectionViewBase.tsx
@@ -17,8 +17,11 @@ export interface CollectionViewProps {
CollectionFieldKey: Key;
DocumentForCollection: Document;
ContainingDocumentView: Opt<DocumentView>;
- GetTransform: () => Transform;
- BackgroundView: Opt<DocumentView>;
+ ScreenToLocalTransform: () => Transform;
+ isSelected: () => boolean;
+ isTopMost: boolean;
+ select: (ctrlPressed: boolean) => void;
+ BackgroundView?: () => JSX.Element;
ParentScaling: number;
}
@@ -28,15 +31,16 @@ export const COLLECTION_BORDER_WIDTH = 2;
export class CollectionViewBase extends React.Component<CollectionViewProps> {
public static LayoutString(collectionType: string, fieldKey: string = "DataKey") {
- return `<${collectionType} ParentScaling={ParentScaling} DocumentForCollection={Document} CollectionFieldKey={${fieldKey}} ContainingDocumentView={DocumentView} BackgroundView={BackgroundView} />`;
+ return `<${collectionType} Scaling={Scaling} DocumentForCollection={Document}
+ ScreenToLocalTransform={ScreenToLocalTransform} CollectionFieldKey={${fieldKey}} isSelected={isSelected} select={select}
+ isTopMost={isTopMost}
+ ContainingDocumentView={DocumentView} BackgroundView={BackgroundView} />`;
}
@computed
public get active(): boolean {
var isSelected = (this.props.ContainingDocumentView instanceof CollectionFreeFormDocumentView && SelectionManager.IsSelected(this.props.ContainingDocumentView));
var childSelected = SelectionManager.SelectedDocuments().some(view => view.props.ContainingCollectionView == this);
- var topMost = this.props.ContainingDocumentView != undefined && (
- this.props.ContainingDocumentView.props.ContainingCollectionView == undefined ||
- this.props.ContainingDocumentView.props.ContainingCollectionView instanceof CollectionDockingView);
+ var topMost = this.props.isTopMost;
return isSelected || childSelected || topMost;
}
@action
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index a2fbe96d2..57527076b 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -14,11 +14,8 @@ import { Transform } from "../../util/Transform";
@observer
-export class CollectionFreeFormDocumentView extends DocumentView {
- private _contextMenuCanOpen = false;
- private _downX: number = 0;
- private _downY: number = 0;
- // private _mainCont = React.createRef<HTMLDivElement>();
+export class CollectionFreeFormDocumentView extends React.Component<DocumentViewProps> {
+ private _mainCont = React.createRef<HTMLDivElement>();
constructor(props: DocumentViewProps) {
super(props);
@@ -30,17 +27,9 @@ export class CollectionFreeFormDocumentView extends DocumentView {
return new DOMRect();
}
- public LeftCorner(): number {
- return this.props.Document.GetNumber(KeyStore.X, 0) + super.LeftCorner();
- }
-
- public TopCorner(): number {
- return this.props.Document.GetNumber(KeyStore.Y, 0) + super.TopCorner();
- }
-
@computed
get transform(): string {
- 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)`;
+ return `scale(${this.props.Scaling}, ${this.props.Scaling}) translate(${this.props.Document.GetNumber(KeyStore.X, 0)}px, ${this.props.Document.GetNumber(KeyStore.Y, 0)}px)`;
}
@computed
@@ -85,151 +74,25 @@ export class CollectionFreeFormDocumentView extends DocumentView {
this.props.Document.SetData(KeyStore.ZIndex, h, NumberField)
}
- @action
- dragComplete = (e: DragManager.DragCompleteEvent) => {
- }
-
- @computed
- get active(): boolean {
- return SelectionManager.IsSelected(this) || this.props.ContainingCollectionView === undefined ||
- this.props.ContainingCollectionView.active;
- }
-
- @computed
- get topMost(): boolean {
- return this.props.ContainingCollectionView == undefined || this.props.ContainingCollectionView instanceof CollectionDockingView;
- }
-
- onPointerDown = (e: React.PointerEvent): void => {
- this._downX = e.clientX;
- this._downY = e.clientY;
- var me = this;
- if (e.shiftKey && e.buttons === 1) {
- CollectionDockingView.StartOtherDrag(this._mainCont.current!, this.props.Document);
- e.stopPropagation();
- return;
- }
- this._contextMenuCanOpen = e.button == 2;
- if (this.active && !e.isDefaultPrevented()) {
- e.stopPropagation();
- if (e.buttons === 2) {
- e.preventDefault();
- }
- document.removeEventListener("pointermove", this.onPointerMove)
- document.addEventListener("pointermove", this.onPointerMove);
- document.removeEventListener("pointerup", this.onPointerUp)
- document.addEventListener("pointerup", this.onPointerUp);
- }
- }
-
- onPointerMove = (e: PointerEvent): void => {
- if (e.cancelBubble) {
- this._contextMenuCanOpen = false;
- return;
- }
- if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) {
- this._contextMenuCanOpen = false;
- if (this._mainCont.current != null && !this.topMost) {
- this._contextMenuCanOpen = false;
- const rect = this.screenRect;
- let dragData: { [id: string]: any } = {};
- dragData["document"] = this;
- dragData["xOffset"] = e.x - rect.left;
- dragData["yOffset"] = e.y - rect.top;
- DragManager.StartDrag(this._mainCont.current, dragData, {
- handlers: {
- dragComplete: this.dragComplete,
- },
- hideSource: true
- })
- }
- }
- e.stopPropagation();
- e.preventDefault();
- }
-
- onPointerUp = (e: PointerEvent): void => {
- document.removeEventListener("pointermove", this.onPointerMove)
- document.removeEventListener("pointerup", this.onPointerUp)
- e.stopPropagation();
- if (Math.abs(e.clientX - this._downX) < 4 && Math.abs(e.clientY - this._downY) < 4) {
- SelectionManager.SelectDoc(this, e.ctrlKey);
- }
- }
-
- openRight = (e: React.MouseEvent): void => {
- CollectionDockingView.AddRightSplit(this.props.Document);
- }
-
- deleteClicked = (e: React.MouseEvent): void => {
- if (this.props.ContainingCollectionView instanceof CollectionFreeFormView) {
- this.props.ContainingCollectionView.removeDocument(this.props.Document)
- }
- }
- @action
- fullScreenClicked = (e: React.MouseEvent): void => {
- CollectionDockingView.OpenFullScreen(this.props.Document);
- ContextMenu.Instance.clearItems();
- ContextMenu.Instance.addItem({ description: "Close Full Screen", event: this.closeFullScreenClicked });
- ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15)
- }
- @action
- closeFullScreenClicked = (e: React.MouseEvent): void => {
- CollectionDockingView.CloseFullScreen();
- ContextMenu.Instance.clearItems();
- ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked })
- ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15)
- }
-
- @action
- onContextMenu = (e: React.MouseEvent): void => {
- if (!SelectionManager.IsSelected(this)) {
- return;
- }
- e.preventDefault()
-
- if (!this._contextMenuCanOpen) {
- return;
- }
-
- if (this.topMost) {
- ContextMenu.Instance.clearItems()
- ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked })
- ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15)
- }
- else {
- // DocumentViews should stop propogation of this event
- e.stopPropagation();
-
- ContextMenu.Instance.clearItems();
- 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.displayMenu(e.pageX - 15, e.pageY - 15)
- SelectionManager.SelectDoc(this, e.ctrlKey);
- }
- }
getTransform = (): Transform => {
- return this.props.GetTransform().translated(this.props.Document.GetNumber(KeyStore.X, 0), this.props.Document.GetNumber(KeyStore.Y, 0));
+ return this.props.ScreenToLocalTransform().translate(-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="documentView-node" ref={this._mainCont}
- onContextMenu={this.onContextMenu}
- 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 ref={this._mainCont} style={{
+ transformOrigin: "left top",
+ transform: this.transform,
+ width: this.width,
+ height: this.height,
+ position: "absolute",
+ zIndex: this.zIndex,
+ backgroundColor: "transparent"
+ }} >
+
+ <DocumentView {...this.props} Scaling={this.width / this.nativeWidth} ScreenToLocalTransform={this.getTransform} />
</div>
);
}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index c5270e0cd..f368fdeaf 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -14,6 +14,10 @@ import { ImageBox } from "../nodes/ImageBox";
import "./DocumentView.scss";
import React = require("react");
import { Transform } from "../../util/Transform";
+import { SelectionManager } from "../../util/SelectionManager";
+import { DragManager } from "../../util/DragManager";
+import { ContextMenu } from "../ContextMenu";
+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 {
@@ -23,32 +27,35 @@ export interface DocumentViewProps {
Document: Document;
AddDocument?: (doc: Document) => void;
RemoveDocument?: (doc: Document) => boolean;
- GetTransform: () => Transform;
- ParentScaling: number;
+ ScreenToLocalTransform: () => Transform;
+ isTopMost: boolean;
+ Scaling: number;
}
@observer
export class DocumentView extends React.Component<DocumentViewProps> {
- protected _renderDoc = React.createRef<any>();
- protected _mainCont = React.createRef<any>();
+ private _mainCont = React.createRef<HTMLDivElement>();
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;
+ get screenRect(): ClientRect | DOMRect {
+ if (this._mainCont.current) {
+ return this._mainCont.current.getBoundingClientRect();
+ }
+ return new DOMRect();
}
-
@computed
get layout(): string {
return this.props.Document.GetText(KeyStore.Layout, "<p>Error loading layout data</p>");
}
@computed
- get backgroundLayout(): string {
- return this.props.Document.GetText(KeyStore.BackgroundLayout, "");
+ get backgroundLayout(): string | undefined {
+ let field = this.props.Document.GetT(KeyStore.BackgroundLayout, TextField);
+ if (field && field !== "<Waiting>") {
+ return field.Data;
+ }
}
@computed
@@ -61,93 +68,159 @@ export class DocumentView extends React.Component<DocumentViewProps> {
return this.props.Document.GetData(KeyStore.LayoutFields, ListField, new Array<Key>());
}
- //
- // returns the cumulative scaling between the document and the screen
- //
@computed
- public get ScalingToScreenSpace(): number {
- if (this.props.ContainingCollectionView != undefined &&
- this.props.ContainingCollectionView.props.ContainingDocumentView != undefined) {
- let ss = this.props.ContainingCollectionView.props.DocumentForCollection.GetNumber(KeyStore.Scale, 1);
- return this.props.ContainingCollectionView.props.ContainingDocumentView.ScalingToScreenSpace * ss;
+ get active(): boolean {
+ return SelectionManager.IsSelected(this) || this.props.ContainingCollectionView === undefined ||
+ this.props.ContainingCollectionView.active;
+ }
+
+ private _contextMenuCanOpen = false;
+ private _downX: number = 0;
+ private _downY: number = 0;
+ onPointerDown = (e: React.PointerEvent): void => {
+ this._downX = e.clientX;
+ this._downY = e.clientY;
+ var me = this;
+ if (e.shiftKey && e.buttons === 1) {
+ CollectionDockingView.StartOtherDrag(this._mainCont.current!, this.props.Document);
+ e.stopPropagation();
+ return;
+ }
+ this._contextMenuCanOpen = e.button == 2;
+ if (this.active && !e.isDefaultPrevented()) {
+ e.stopPropagation();
+ if (e.buttons === 2) {
+ e.preventDefault();
+ }
+ document.removeEventListener("pointermove", this.onPointerMove)
+ document.addEventListener("pointermove", this.onPointerMove);
+ document.removeEventListener("pointerup", this.onPointerUp)
+ document.addEventListener("pointerup", this.onPointerUp);
}
- return 1;
}
+ @action
+ dragComplete = (e: DragManager.DragCompleteEvent) => {
+ }
+
+ @computed
+ get topMost(): boolean {
+ return this.props.ContainingCollectionView == undefined || this.props.ContainingCollectionView instanceof CollectionDockingView;
+ }
- 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;
+ onPointerMove = (e: PointerEvent): void => {
+ if (e.cancelBubble) {
+ this._contextMenuCanOpen = false;
+ return;
+ }
+ if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) {
+ this._contextMenuCanOpen = false;
+ if (this._mainCont.current != null && !this.topMost) {
+ this._contextMenuCanOpen = false;
+ const [left, top] = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
+ let dragData: { [id: string]: any } = {};
+ dragData["document"] = this;
+ dragData["xOffset"] = e.x - left;
+ dragData["yOffset"] = e.y - top;
+ DragManager.StartDrag(this._mainCont.current, dragData, {
+ handlers: {
+ dragComplete: this.dragComplete,
+ },
+ hideSource: true
+ })
}
- return COLLECTION_BORDER_WIDTH; // assumes all collections have the same border
}
- return 0;
+ e.stopPropagation();
+ e.preventDefault();
}
- 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
+ onPointerUp = (e: PointerEvent): void => {
+ document.removeEventListener("pointermove", this.onPointerMove)
+ document.removeEventListener("pointerup", this.onPointerUp)
+ e.stopPropagation();
+ if (Math.abs(e.clientX - this._downX) < 4 && Math.abs(e.clientY - this._downY) < 4) {
+ SelectionManager.SelectDoc(this, e.ctrlKey);
}
- return 0;
}
- //
- // 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 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;
- let Ss = this.props.Document.GetNumber(KeyStore.Scale, 1);
- 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;
+ openRight = (e: React.MouseEvent): void => {
+ CollectionDockingView.AddRightSplit(this.props.Document);
+ }
+
+ deleteClicked = (e: React.MouseEvent): void => {
+ if (this.props.RemoveDocument) {
+ this.props.RemoveDocument(this.props.Document);
+ }
+ }
+ @action
+ fullScreenClicked = (e: React.MouseEvent): void => {
+ CollectionDockingView.OpenFullScreen(this.props.Document);
+ ContextMenu.Instance.clearItems();
+ ContextMenu.Instance.addItem({ description: "Close Full Screen", event: this.closeFullScreenClicked });
+ ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15)
+ }
+ @action
+ closeFullScreenClicked = (e: React.MouseEvent): void => {
+ CollectionDockingView.CloseFullScreen();
+ ContextMenu.Instance.clearItems();
+ ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked })
+ ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15)
+ }
+
+ @action
+ onContextMenu = (e: React.MouseEvent): void => {
+ if (!SelectionManager.IsSelected(this)) {
+ return;
+ }
+ e.preventDefault()
+
+ if (!this._contextMenuCanOpen) {
+ return;
+ }
+
+ if (this.topMost) {
+ ContextMenu.Instance.clearItems()
+ ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked })
+ ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15)
+ }
+ else {
+ // DocumentViews should stop propogation of this event
+ e.stopPropagation();
- return { LocalX, LocalY, ContainerX, ContainerY };
+ ContextMenu.Instance.clearItems();
+ 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.displayMenu(e.pageX - 15, e.pageY - 15)
+ SelectionManager.SelectDoc(this, e.ctrlKey);
+ }
}
+ //
+ // returns the cumulative scaling between the document and the screen
//
- // Converts a point in the coordinate space of the document to coordinate in app screen coordinates
- //
- 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 ? 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;
+ @computed
+ public get ScalingToScreenSpace(): number {
+ if (this.props.ContainingCollectionView != undefined &&
+ this.props.ContainingCollectionView.props.ContainingDocumentView != undefined) {
+ let ss = this.props.ContainingCollectionView.props.DocumentForCollection.GetNumber(KeyStore.Scale, 1);
+ return this.props.ContainingCollectionView.props.ContainingDocumentView.ScalingToScreenSpace * ss;
}
- return { ScreenX: parentX, ScreenY: parentY };
+ return 1;
+ }
+
+ isSelected = () => {
+ return SelectionManager.IsSelected(this);
+ }
+
+ select = (ctrlPressed: boolean) => {
+ SelectionManager.SelectDoc(this, ctrlPressed)
}
render() {
let bindings = { ...this.props } as any;
+ bindings.isSelected = this.isSelected;
+ bindings.select = this.select;
for (const key of this.layoutKeys) {
bindings[key.Name + "Key"] = key; // this maps string values of the form <keyname>Key to an actual key Kestore.keyname e.g, "DataKey" => KeyStore.Data
}
@@ -155,33 +228,33 @@ export class DocumentView extends React.Component<DocumentViewProps> {
let field = this.props.Document.Get(key);
bindings[key.Name] = field && field != FieldWaiting ? field.GetValue() : field;
}
- 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.
- }
- if (this.backgroundLayout) {
- var backgroundview = <JsxParser
- components={{ FormattedTextBox: FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }}
+ /*
+ Should this be moved to CollectionFreeformView or another component that renders
+ Document backgrounds (or contents based on a layout key, which could be used here as well)
+ that CollectionFreeformView uses? It seems like a lot for it to be here considering only one view currently uses it...
+ */
+ let backgroundLayout = this.backgroundLayout;
+ if (backgroundLayout) {
+ let backgroundView = () => (<JsxParser
+ components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }}
bindings={bindings}
jsx={this.backgroundLayout}
showWarnings={true}
onError={(test: any) => { console.log(test) }}
- />;
- bindings["BackgroundView"] = backgroundview;
+ />);
+ 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%";
+
+ var width = this.props.Document.GetNumber(KeyStore.NativeWidth, 0);
+ var strwidth = width > 0 ? width.toString() + "px" : "100%";
+ var height = this.props.Document.GetNumber(KeyStore.NativeHeight, 0);
+ var strheight = height > 0 ? height.toString() + "px" : "100%";
return (
- <div className="documentView-node" ref={this._mainCont}
- style={{
- width: width,
- height: height,
- transformOrigin: "top left",
- transform: `scale(${this.props.ParentScaling},${this.props.ParentScaling})`
- }}>
+ <div className="documentView-node" ref={this._mainCont} style={{ width: strwidth, height: strheight, transformOrigin: "left top", transform: `scale(${this.props.Scaling},${this.props.Scaling})` }}
+ onContextMenu={this.onContextMenu}
+ onPointerDown={this.onPointerDown} >
<JsxParser
- components={{ FormattedTextBox: FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }}
+ components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }}
bindings={bindings}
jsx={this.layout}
showWarnings={true}
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 12371eb2e..08de53e1c 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -10,7 +10,6 @@ import { ImageField } from "../../../fields/ImageField";
import { Key } from "../../../fields/Key";
import { FormattedTextBox } from "./FormattedTextBox";
import { ImageBox } from "./ImageBox";
-import { DocumentView } from "./DocumentView";
//
// these properties get assigned through the render() method of the DocumentView when it creates this node.
@@ -20,12 +19,13 @@ import { DocumentView } from "./DocumentView";
export interface FieldViewProps {
fieldKey: Key;
doc: Document;
- DocumentViewForField: Opt<DocumentView>
+ isSelected: () => boolean;
+ isTopMost: boolean;
}
@observer
export class FieldView extends React.Component<FieldViewProps> {
- public static LayoutString(fieldType: string) { return `<${fieldType} doc={Document} DocumentViewForField={DocumentView} fieldKey={DataKey} />`; }
+ public static LayoutString(fieldType: string) { return `<${fieldType} doc={Document} DocumentViewForField={DocumentView} fieldKey={DataKey} isSelected={isSelected} isTopMost={isTopMost} />`; }
@computed
get field(): FieldValue<Field> {
const { doc, fieldKey } = this.props;
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index f6bd0c0f8..2e3d396c1 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -110,7 +110,7 @@ export class FormattedTextBox extends React.Component<FieldViewProps> {
}
onPointerDown = (e: React.PointerEvent): void => {
let me = this;
- if (e.buttons === 1 && me.props.DocumentViewForField instanceof CollectionFreeFormDocumentView && SelectionManager.IsSelected(me.props.DocumentViewForField)) {
+ if (e.buttons === 1 && this.props.isSelected()) {
e.stopPropagation();
}
}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 2fa70734d..e1fa26e2f 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -41,7 +41,7 @@ export class ImageBox extends React.Component<FieldViewProps> {
onPointerDown = (e: React.PointerEvent): void => {
if (Date.now() - this._lastTap < 300) {
- if (e.buttons === 1 && this.props.DocumentViewForField instanceof CollectionFreeFormDocumentView && SelectionManager.IsSelected(this.props.DocumentViewForField)) {
+ if (e.buttons === 1 && this.props.isSelected()) {
e.stopPropagation();
this._downX = e.clientX;
this._downY = e.clientY;
@@ -63,7 +63,7 @@ export class ImageBox extends React.Component<FieldViewProps> {
lightbox = (path: string) => {
const images = [path, "http://www.cs.brown.edu/~bcz/face.gif"];
- if (this._isOpen && this.props.DocumentViewForField instanceof CollectionFreeFormDocumentView && SelectionManager.IsSelected(this.props.DocumentViewForField)) {
+ if (this._isOpen && this.props.isSelected()) {
return (<Lightbox
mainSrc={images[this._photoIndex]}
nextSrc={images[(this._photoIndex + 1) % images.length]}