aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
diff options
context:
space:
mode:
authorBob Zeleznik <zzzman@gmail.com>2019-04-30 21:51:01 -0400
committerBob Zeleznik <zzzman@gmail.com>2019-04-30 21:51:01 -0400
commite0375046dd873745f51263c215395843e7b6c2ce (patch)
tree52e085050f3af8fe4832e5f172893848653ac001 /src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
parent32ad476cb98d140586af8147c3d2431623325385 (diff)
parent86e89178628a27a91665ad835046e536bdb89729 (diff)
merged with master
Diffstat (limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx')
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx437
1 files changed, 226 insertions, 211 deletions
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 4562fd8a7..2fa59d589 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,58 +1,63 @@
-import { action, computed, observable, trace, ObservableSet, runInAction } from "mobx";
+import { action, computed } from "mobx";
import { observer } from "mobx-react";
import { Document } from "../../../../fields/Document";
-import { FieldWaiting } from "../../../../fields/Field";
import { KeyStore } from "../../../../fields/KeyStore";
-import { TextField } from "../../../../fields/TextField";
+import { emptyFunction, returnFalse, returnOne } from "../../../../Utils";
+import { DocumentManager } from "../../../util/DocumentManager";
import { DragManager } from "../../../util/DragManager";
+import { SelectionManager } from "../../../util/SelectionManager";
import { Transform } from "../../../util/Transform";
import { undoBatch } from "../../../util/UndoManager";
+import { COLLECTION_BORDER_WIDTH } from "../../../views/globalCssVariables.scss";
import { InkingCanvas } from "../../InkingCanvas";
import { CollectionFreeFormDocumentView } from "../../nodes/CollectionFreeFormDocumentView";
import { DocumentContentsView } from "../../nodes/DocumentContentsView";
import { DocumentViewProps } from "../../nodes/DocumentView";
-import { COLLECTION_BORDER_WIDTH } from "../CollectionBaseView";
import { CollectionSubView } from "../CollectionSubView";
import { CollectionFreeFormLinksView } from "./CollectionFreeFormLinksView";
+import { CollectionFreeFormRemoteCursors } from "./CollectionFreeFormRemoteCursors";
import "./CollectionFreeFormView.scss";
import { MarqueeView } from "./MarqueeView";
import React = require("react");
import v5 = require("uuid/v5");
-import { CollectionFreeFormRemoteCursors } from "./CollectionFreeFormRemoteCursors";
-import { PreviewCursor } from "./PreviewCursor";
-import { DocumentManager } from "../../../util/DocumentManager";
-import { SelectionManager } from "../../../util/SelectionManager";
-import { NumberField } from "../../../../fields/NumberField";
-import { Main } from "../../Main";
-import Measure from "react-measure";
+import { BooleanField } from "../../../../fields/BooleanField";
@observer
export class CollectionFreeFormView extends CollectionSubView {
- public _canvasRef = React.createRef<HTMLDivElement>();
+ public static RIGHT_BTN_DRAG = false;
private _selectOnLoaded: string = ""; // id of document that should be selected once it's loaded (used for click-to-type)
+ private _lastX: number = 0;
+ private _lastY: number = 0;
+ private get _pwidth() { return this.props.PanelWidth(); }
+ private get _pheight() { return this.props.PanelHeight(); }
- public addLiveTextBox = (newBox: Document) => {
- // mark this collection so that when the text box is created we can send it the SelectOnLoad prop to focus itself and receive text input
- this._selectOnLoaded = newBox.Id;
+ @computed get nativeWidth() { return this.props.Document.GetNumber(KeyStore.NativeWidth, 0); }
+ @computed get nativeHeight() { return this.props.Document.GetNumber(KeyStore.NativeHeight, 0); }
+ private get borderWidth() { return this.isAnnotationOverlay ? 0 : COLLECTION_BORDER_WIDTH; }
+ private get isAnnotationOverlay() { return this.props.fieldKey && this.props.fieldKey.Id === KeyStore.Annotations.Id; } // bcz: ? Why do we need to compare Id's?
+ private panX = () => this.props.Document.GetNumber(KeyStore.PanX, 0);
+ private panY = () => this.props.Document.GetNumber(KeyStore.PanY, 0);
+ private zoomScaling = () => this.props.Document.GetNumber(KeyStore.Scale, 1);
+ private centeringShiftX = () => !this.nativeWidth ? this._pwidth / 2 : 0; // shift so pan position is at center of window for non-overlay collections
+ private centeringShiftY = () => !this.nativeHeight ? this._pheight / 2 : 0;// shift so pan position is at center of window for non-overlay collections
+ private getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.borderWidth, -this.borderWidth).translate(-this.centeringShiftX(), -this.centeringShiftY()).transform(this.getLocalTransform());
+ private getContainerTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.borderWidth, -this.borderWidth);
+ private getLocalTransform = (): Transform => Transform.Identity().scale(1 / this.zoomScaling()).translate(this.panX(), this.panY());
+ private addLiveTextBox = (newBox: Document) => {
+ this._selectOnLoaded = newBox.Id;// track the new text box so we can give it a prop that tells it to focus itself when it's displayed
this.addDocument(newBox, false);
}
-
- public addDocument = (newBox: Document, allowDuplicates: boolean) => {
- let added = this.props.addDocument(newBox, false);
+ @action
+ private addDocument = (newBox: Document, allowDuplicates: boolean) => {
+ this.props.addDocument(newBox, false);
this.bringToFront(newBox);
- return added;
+ return true;
}
-
- public selectDocuments = (docs: Document[]) => {
+ private selectDocuments = (docs: Document[]) => {
SelectionManager.DeselectAll;
- docs.map(doc => {
- const dv = DocumentManager.Instance.getDocumentView(doc);
- if (dv) {
- SelectionManager.SelectDoc(dv, true);
- }
- });
+ docs.map(doc => DocumentManager.Instance.getDocumentView(doc)).filter(dv => dv).map(dv =>
+ SelectionManager.SelectDoc(dv!, true));
}
-
public getActiveDocuments = () => {
var curPage = this.props.Document.GetNumber(KeyStore.CurPage, -1);
return this.props.Document.GetList(this.props.fieldKey, [] as Document[]).reduce((active, doc) => {
@@ -64,61 +69,38 @@ export class CollectionFreeFormView extends CollectionSubView {
}, [] as Document[]);
}
- @observable public DownX: number = 0;
- @observable public DownY: number = 0;
- @observable private _lastX: number = 0;
- @observable private _lastY: number = 0;
- @observable private _pwidth: number = 0;
- @observable private _pheight: number = 0;
-
- @computed get panX(): number { return this.props.Document.GetNumber(KeyStore.PanX, 0); }
- @computed get panY(): number { return this.props.Document.GetNumber(KeyStore.PanY, 0); }
- @computed get scale(): number { return this.props.Document.GetNumber(KeyStore.Scale, 1); }
- @computed get isAnnotationOverlay() { return this.props.fieldKey && this.props.fieldKey.Id === KeyStore.Annotations.Id; } // bcz: ? Why do we need to compare Id's?
- @computed get nativeWidth() { return this.props.Document.GetNumber(KeyStore.NativeWidth, 0); }
- @computed get nativeHeight() { return this.props.Document.GetNumber(KeyStore.NativeHeight, 0); }
- @computed get zoomScaling() { return this.props.Document.GetNumber(KeyStore.Scale, 1); }
- @computed get centeringShiftX() { return !this.props.Document.GetNumber(KeyStore.NativeWidth, 0) ? this._pwidth / 2 : 0; } // shift so pan position is at center of window for non-overlay collections
- @computed get centeringShiftY() { return !this.props.Document.GetNumber(KeyStore.NativeHeight, 0) ? this._pheight / 2 : 0; }// shift so pan position is at center of window for non-overlay collections
-
@undoBatch
@action
drop = (e: Event, de: DragManager.DropEvent) => {
- if (super.drop(e, de)) {
- if (de.data instanceof DragManager.DocumentDragData) {
- let droppedDocs = de.data.droppedDocuments;
- let xoff = de.data.xOffset as number || 0;
- let yoff = de.data.yOffset as number || 0;
- if (droppedDocs.length) {
- let screenX = de.x - xoff;
- let screenY = de.y - yoff;
- const [x, y] = this.getTransform().transformPoint(screenX, screenY);
- let dragDoc = droppedDocs[0];
- let dragX = dragDoc.GetNumber(KeyStore.X, 0);
- let dragY = dragDoc.GetNumber(KeyStore.Y, 0);
- droppedDocs.map(async d => {
- let docX = d.GetNumber(KeyStore.X, 0);
- let docY = d.GetNumber(KeyStore.Y, 0);
- d.SetNumber(KeyStore.X, x + (docX - dragX));
- d.SetNumber(KeyStore.Y, y + (docY - dragY));
- let docW = await d.GetTAsync(KeyStore.Width, NumberField);
- let docH = await d.GetTAsync(KeyStore.Height, NumberField);
- if (!docW) {
- d.SetNumber(KeyStore.Width, 300);
- }
- if (!docH) {
- d.SetNumber(KeyStore.Height, 300);
- }
- this.bringToFront(d);
- });
- }
+ if (super.drop(e, de) && de.data instanceof DragManager.DocumentDragData) {
+ if (de.data.droppedDocuments.length) {
+ let dragDoc = de.data.droppedDocuments[0];
+ let zoom = dragDoc.GetNumber(KeyStore.ZoomBasis, 1);
+ let [xp, yp] = this.getTransform().transformPoint(de.x, de.y);
+ let x = xp - de.data.xOffset / zoom;
+ let y = yp - de.data.yOffset / zoom;
+ let dropX = de.data.droppedDocuments[0].GetNumber(KeyStore.X, 0);
+ let dropY = de.data.droppedDocuments[0].GetNumber(KeyStore.Y, 0);
+ de.data.droppedDocuments.map(d => {
+ d.SetNumber(KeyStore.X, x + (d.GetNumber(KeyStore.X, 0) - dropX));
+ d.SetNumber(KeyStore.Y, y + (d.GetNumber(KeyStore.Y, 0) - dropY));
+ if (!d.GetNumber(KeyStore.Width, 0)) {
+ d.SetNumber(KeyStore.Width, 300);
+ }
+ if (!d.GetNumber(KeyStore.Height, 0)) {
+ let nw = d.GetNumber(KeyStore.NativeWidth, 0);
+ let nh = d.GetNumber(KeyStore.NativeHeight, 0);
+ d.SetNumber(KeyStore.Height, nw && nh ? nh / nw * d.Width() : 300);
+ }
+ this.bringToFront(d);
+ });
+ SelectionManager.ReselectAll();
}
return true;
}
return false;
}
-
@action
cleanupInteractions = () => {
document.removeEventListener("pointermove", this.onPointerMove);
@@ -127,83 +109,106 @@ export class CollectionFreeFormView extends CollectionSubView {
@action
onPointerDown = (e: React.PointerEvent): void => {
- if (((e.button === 2 && (!this.isAnnotationOverlay || this.zoomScaling !== 1)) || e.button === 0) && this.props.active()) {
- document.removeEventListener("pointermove", this.onPointerMove);
+ let childSelected = this.props.Document.GetList(this.props.fieldKey, [] as Document[]).filter(doc => doc).reduce((childSelected, doc) => {
+ var dv = DocumentManager.Instance.getDocumentView(doc);
+ return childSelected || (dv && SelectionManager.IsSelected(dv) ? true : false);
+ }, false);
+ if ((CollectionFreeFormView.RIGHT_BTN_DRAG &&
+ (((e.button === 2 && (!this.isAnnotationOverlay || this.zoomScaling() !== 1)) ||
+ (e.button === 0 && e.altKey)) && (childSelected || this.props.active()))) ||
+ (!CollectionFreeFormView.RIGHT_BTN_DRAG &&
+ ((e.button === 0 && !e.altKey && (!this.isAnnotationOverlay || this.zoomScaling() !== 1)) && (childSelected || this.props.active())))) {
+ this.cleanupInteractions();
document.addEventListener("pointermove", this.onPointerMove);
- document.removeEventListener("pointerup", this.onPointerUp);
document.addEventListener("pointerup", this.onPointerUp);
- this._lastX = this.DownX = e.pageX;
- this._lastY = this.DownY = e.pageY;
- if (this.props.isSelected()) {
- e.stopPropagation();
- }
+ this._lastX = e.pageX;
+ this._lastY = e.pageY;
}
}
- @action
onPointerUp = (e: PointerEvent): void => {
- e.stopPropagation();
-
this.cleanupInteractions();
}
@action
onPointerMove = (e: PointerEvent): void => {
- if (!e.cancelBubble && this.props.active()) {
- if ((!this.isAnnotationOverlay || this.zoomScaling !== 1) && !e.shiftKey) {
- let x = this.props.Document.GetNumber(KeyStore.PanX, 0);
- let y = this.props.Document.GetNumber(KeyStore.PanY, 0);
- let [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
- this.SetPan(x - dx, y - dy);
- this._lastX = e.pageX;
- this._lastY = e.pageY;
- e.stopPropagation();
- e.preventDefault();
+ if (!e.cancelBubble) {
+ let x = this.props.Document.GetNumber(KeyStore.PanX, 0);
+ let y = this.props.Document.GetNumber(KeyStore.PanY, 0);
+ let docs = this.props.Document.GetList(this.props.fieldKey, [] as Document[]);
+ let [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
+ if (!this.isAnnotationOverlay) {
+ let minx = docs.length ? docs[0].GetNumber(KeyStore.X, 0) : 0;
+ let maxx = docs.length ? docs[0].Width() + minx : minx;
+ let miny = docs.length ? docs[0].GetNumber(KeyStore.Y, 0) : 0;
+ let maxy = docs.length ? docs[0].Height() + miny : miny;
+ let ranges = docs.filter(doc => doc).reduce((range, doc) => {
+ let x = doc.GetNumber(KeyStore.X, 0);
+ let xe = x + doc.GetNumber(KeyStore.Width, 0);
+ let y = doc.GetNumber(KeyStore.Y, 0);
+ let ye = y + doc.GetNumber(KeyStore.Height, 0);
+ return [[range[0][0] > x ? x : range[0][0], range[0][1] < xe ? xe : range[0][1]],
+ [range[1][0] > y ? y : range[1][0], range[1][1] < ye ? ye : range[1][1]]];
+ }, [[minx, maxx], [miny, maxy]]);
+ let panelwidth = this._pwidth / this.zoomScaling() / 2;
+ let panelheight = this._pheight / this.zoomScaling() / 2;
+ if (x - dx < ranges[0][0] - panelwidth) x = ranges[0][1] + panelwidth + dx;
+ if (x - dx > ranges[0][1] + panelwidth) x = ranges[0][0] - panelwidth + dx;
+ if (y - dy < ranges[1][0] - panelheight) y = ranges[1][1] + panelheight + dy;
+ if (y - dy > ranges[1][1] + panelheight) y = ranges[1][0] - panelheight + dy;
}
+ this.setPan(x - dx, y - dy);
+ this._lastX = e.pageX;
+ this._lastY = e.pageY;
+ e.stopPropagation(); // doesn't actually stop propagation since all our listeners are listening to events on 'document' however it does mark the event as cancelBubble=true which we test for in the move event handlers
+ e.preventDefault();
}
}
@action
onPointerWheel = (e: React.WheelEvent): void => {
- this.props.select(false);
+ // if (!this.props.active()) {
+ // return;
+ // }
+ let childSelected = this.props.Document.GetList(this.props.fieldKey, [] as Document[]).filter(doc => doc).reduce((childSelected, doc) => {
+ var dv = DocumentManager.Instance.getDocumentView(doc);
+ return childSelected || (dv && SelectionManager.IsSelected(dv) ? true : false);
+ }, false);
+ if (!this.props.isSelected() && !childSelected && !this.props.isTopMost) {
+ return;
+ }
e.stopPropagation();
- let coefficient = 1000;
+ const coefficient = 1000;
if (e.ctrlKey) {
- var nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 0);
- var nativeHeight = this.props.Document.GetNumber(KeyStore.NativeHeight, 0);
- const coefficient = 1000;
let deltaScale = (1 - (e.deltaY / coefficient));
- this.props.Document.SetNumber(KeyStore.NativeWidth, nativeWidth * deltaScale);
- this.props.Document.SetNumber(KeyStore.NativeHeight, nativeHeight * deltaScale);
+ this.props.Document.SetNumber(KeyStore.NativeWidth, this.nativeWidth * deltaScale);
+ this.props.Document.SetNumber(KeyStore.NativeHeight, this.nativeHeight * deltaScale);
e.stopPropagation();
e.preventDefault();
} else {
// 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));
- if (deltaScale * this.zoomScaling < 1 && this.isAnnotationOverlay) {
- deltaScale = 1 / this.zoomScaling;
+ if (deltaScale * this.zoomScaling() < 1 && this.isAnnotationOverlay) {
+ deltaScale = 1 / this.zoomScaling();
}
- let [x, y] = transform.transformPoint(e.clientX, e.clientY);
-
- let localTransform = this.getLocalTransform();
- localTransform = localTransform.inverse().scaleAbout(deltaScale, x, y);
- // console.log(localTransform)
+ if (deltaScale < 0) deltaScale = -deltaScale;
+ let [x, y] = this.getTransform().transformPoint(e.clientX, e.clientY);
+ let localTransform = this.getLocalTransform().inverse().scaleAbout(deltaScale, x, y);
- this.props.Document.SetNumber(KeyStore.Scale, localTransform.Scale);
- this.SetPan(-localTransform.TranslateX / localTransform.Scale, -localTransform.TranslateY / localTransform.Scale);
+ let safeScale = Math.abs(localTransform.Scale);
+ this.props.Document.SetNumber(KeyStore.Scale, Math.abs(safeScale));
+ this.setPan(-localTransform.TranslateX / safeScale, -localTransform.TranslateY / safeScale);
+ e.stopPropagation();
}
}
@action
- private SetPan(panX: number, panY: number) {
- Main.Instance.SetTextDoc(undefined, undefined);
- var x1 = this.getLocalTransform().inverse().Scale;
- const newPanX = Math.min((1 - 1 / x1) * this.nativeWidth, Math.max(0, panX));
- const newPanY = Math.min((1 - 1 / x1) * this.nativeHeight, Math.max(0, panY));
+ setPan(panX: number, panY: number) {
+ var scale = this.getLocalTransform().inverse().Scale;
+ const newPanX = Math.min((1 - 1 / scale) * this.nativeWidth, Math.max(0, panX));
+ const newPanY = Math.min((1 - 1 / scale) * this.nativeHeight, Math.max(0, panY));
this.props.Document.SetNumber(KeyStore.PanX, this.isAnnotationOverlay ? newPanX : panX);
this.props.Document.SetNumber(KeyStore.PanY, this.isAnnotationOverlay ? newPanY : panY);
@@ -220,51 +225,31 @@ export class CollectionFreeFormView extends CollectionSubView {
@action
bringToFront(doc: Document) {
- const { fieldKey: fieldKey, Document: Document } = this.props;
-
- const value: Document[] = Document.GetList<Document>(fieldKey, []).slice();
- value.sort((doc1, doc2) => {
- if (doc1 === doc) {
- return 1;
- }
- if (doc2 === doc) {
- return -1;
- }
+ let docs = this.props.Document.GetList(this.props.fieldKey, [] as Document[]).slice();
+ docs.sort((doc1, doc2) => {
+ if (doc1 === doc) return 1;
+ if (doc2 === doc) return -1;
return doc1.GetNumber(KeyStore.ZIndex, 0) - doc2.GetNumber(KeyStore.ZIndex, 0);
- }).map((doc, index) => {
- doc.SetNumber(KeyStore.ZIndex, index + 1);
- });
- }
-
- @computed get backgroundLayout(): string | undefined {
- let field = this.props.Document.GetT(KeyStore.BackgroundLayout, TextField);
- if (field && field !== FieldWaiting) {
- return field.Data;
- }
- }
- @computed get overlayLayout(): string | undefined {
- let field = this.props.Document.GetT(KeyStore.OverlayLayout, TextField);
- if (field && field !== FieldWaiting) {
- return field.Data;
- }
+ }).map((doc, index) => doc.SetNumber(KeyStore.ZIndex, index + 1));
+ doc.SetNumber(KeyStore.ZIndex, docs.length + 1);
}
focusDocument = (doc: Document) => {
+ SelectionManager.DeselectAll();
this.props.Document.SetText(KeyStore.PanTransformType, "Ease");
- let x = doc.GetNumber(KeyStore.X, 0) + doc.GetNumber(KeyStore.Width, 0) / 2;
- let y = doc.GetNumber(KeyStore.Y, 0) + doc.GetNumber(KeyStore.Height, 0) / 2;
- this.SetPan(x, y);
+ this.setPan(
+ doc.GetNumber(KeyStore.X, 0) + doc.Width() / 2,
+ doc.GetNumber(KeyStore.Y, 0) + doc.Height() / 2);
this.props.focus(this.props.Document);
- // if(this.props.Document.GetText(KeyStore.PanTransformType, "") === "Ease") {
- // setTimeout(function(){
- // this.props.Document.SetText(KeyStore.PanTransformType, "None");
- // }.bind(this),5000); // wait 5 seconds, then reset to false
- // }
+ if (this.props.Document.GetText(KeyStore.PanTransformType, "") === "Ease") {
+ setTimeout(() => this.props.Document.SetText(KeyStore.PanTransformType, "None"), 5000); // wait 5 seconds, then reset to false
+ }
}
getDocumentViewProps(document: Document): DocumentViewProps {
return {
Document: document,
+ toggleMinimized: emptyFunction,
addDocument: this.props.addDocument,
removeDocument: this.props.removeDocument,
moveDocument: this.props.moveDocument,
@@ -273,86 +258,116 @@ export class CollectionFreeFormView extends CollectionSubView {
selectOnLoad: document.Id === this._selectOnLoaded,
PanelWidth: document.Width,
PanelHeight: document.Height,
- ContentScaling: this.noScaling,
- ContainingCollectionView: undefined,
+ ContentScaling: returnOne,
+ ContainingCollectionView: this.props.CollectionView,
focus: this.focusDocument,
parentActive: this.props.active,
- onActiveChanged: this.props.active,
+ whenActiveChanged: this.props.active,
};
}
@computed
get views() {
var curPage = this.props.Document.GetNumber(KeyStore.CurPage, -1);
- return this.props.Document.GetList(this.props.fieldKey, [] as Document[]).filter(doc => doc).reduce((prev, doc) => {
+ let docviews = this.props.Document.GetList(this.props.fieldKey, [] as Document[]).filter(doc => doc).reduce((prev, doc) => {
var page = doc.GetNumber(KeyStore.Page, -1);
if (page === curPage || page === -1) {
- prev.push(<CollectionFreeFormDocumentView key={doc.Id} {...this.getDocumentViewProps(doc)} />);
+ let minim = doc.GetT(KeyStore.IsMinimized, BooleanField);
+ if (minim === undefined || (minim && !minim.Data))
+ prev.push(<CollectionFreeFormDocumentView key={doc.Id} {...this.getDocumentViewProps(doc)} />);
}
return prev;
}, [] as JSX.Element[]);
- }
- @computed
- get backgroundView() {
- return !this.backgroundLayout ? (null) :
- (<DocumentContentsView {...this.getDocumentViewProps(this.props.Document)}
- layoutKey={KeyStore.BackgroundLayout} isTopMost={this.props.isTopMost} isSelected={() => false} select={() => { }} />);
+ setTimeout(() => this._selectOnLoaded = "", 600);// bcz: surely there must be a better way ....
+
+ return docviews;
}
- @computed
- get overlayView() {
- return !this.overlayLayout ? (null) :
- (<DocumentContentsView {...this.getDocumentViewProps(this.props.Document)}
- layoutKey={KeyStore.OverlayLayout} isTopMost={this.props.isTopMost} isSelected={() => false} select={() => { }} />);
+
+ @action
+ onCursorMove = (e: React.PointerEvent) => {
+ super.setCursorPosition(this.getTransform().transformPoint(e.clientX, e.clientY));
}
- getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-COLLECTION_BORDER_WIDTH, -COLLECTION_BORDER_WIDTH).translate(-this.centeringShiftX, -this.centeringShiftY).transform(this.getLocalTransform());
- getContainerTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-COLLECTION_BORDER_WIDTH, -COLLECTION_BORDER_WIDTH);
- getLocalTransform = (): Transform => Transform.Identity().scale(1 / this.scale).translate(this.panX, this.panY);
- noScaling = () => 1;
- childViews = () => this.views;
+ private childViews = () => [...this.views, <CollectionFreeFormBackgroundView key="backgroundView" {...this.props} {...this.getDocumentViewProps(this.props.Document)} />];
+ render() {
+ const containerName = `collectionfreeformview${this.isAnnotationOverlay ? "-overlay" : "-container"}`;
+ const easing = () => this.props.Document.GetText(KeyStore.PanTransformType, "") === "Ease";
+ return (
+ <div className={containerName} ref={this.createDropTarget} onWheel={this.onPointerWheel}
+ style={{ borderRadius: "inherit" }}
+ onPointerDown={this.onPointerDown} onPointerMove={this.onCursorMove} onDrop={this.onDrop.bind(this)} onDragOver={this.onDragOver} >
+ {/* <svg viewBox="0 0 180 18" style={{ top: "50%", opacity: 0.05, position: "absolute" }}>
+ <text y="15" >
+ {this.props.Document.Title}
+ </text>
+ </svg> */}
+ <MarqueeView container={this} activeDocuments={this.getActiveDocuments} selectDocuments={this.selectDocuments} isSelected={this.props.isSelected}
+ addDocument={this.addDocument} removeDocument={this.props.removeDocument} addLiveTextDocument={this.addLiveTextBox}
+ getContainerTransform={this.getContainerTransform} getTransform={this.getTransform}>
+ <CollectionFreeFormViewPannableContents centeringShiftX={this.centeringShiftX} centeringShiftY={this.centeringShiftY}
+ easing={easing} zoomScaling={this.zoomScaling} panX={this.panX} panY={this.panY}>
+
+ <CollectionFreeFormLinksView {...this.props} key="freeformLinks">
+ <InkingCanvas getScreenTransform={this.getTransform} Document={this.props.Document} >
+ {this.childViews}
+ </InkingCanvas>
+ </CollectionFreeFormLinksView>
+ <CollectionFreeFormRemoteCursors {...this.props} key="remoteCursors" />]
+ </CollectionFreeFormViewPannableContents>
+ <CollectionFreeFormOverlayView {...this.getDocumentViewProps(this.props.Document)} {...this.props} />
+ </MarqueeView>
+ </div>
+ );
+ }
+}
+@observer
+class CollectionFreeFormOverlayView extends React.Component<DocumentViewProps> {
+ @computed get overlayView() {
+ let overlayLayout = this.props.Document.GetText(KeyStore.OverlayLayout, "");
+ return !overlayLayout ? (null) :
+ (<DocumentContentsView {...this.props} layoutKey={KeyStore.OverlayLayout}
+ isTopMost={this.props.isTopMost} isSelected={returnFalse} select={emptyFunction} />);
+ }
render() {
- let [dx, dy] = [this.centeringShiftX, this.centeringShiftY];
+ return this.overlayView;
+ }
+}
- const panx: number = -this.props.Document.GetNumber(KeyStore.PanX, 0);
- const pany: number = -this.props.Document.GetNumber(KeyStore.PanY, 0);
+@observer
+class CollectionFreeFormBackgroundView extends React.Component<DocumentViewProps & { isSelected: () => boolean }> {
+ @computed get backgroundView() {
+ let backgroundLayout = this.props.Document.GetText(KeyStore.BackgroundLayout, "");
+ return !backgroundLayout ? (null) :
+ (<DocumentContentsView {...this.props} layoutKey={KeyStore.BackgroundLayout}
+ isTopMost={this.props.isTopMost} isSelected={this.props.isSelected} select={emptyFunction} />);
+ }
+ render() {
+ return this.backgroundView;
+ }
+}
- if (this.props.Document.GetText(KeyStore.PanTransformType, "") === "Ease") {
- var freeformclass = "collectionfreeformview-ease";
- } else {
- var freeformclass = "collectionfreeformview-none";
- }
+interface CollectionFreeFormViewPannableContentsProps {
+ centeringShiftX: () => number;
+ centeringShiftY: () => number;
+ panX: () => number;
+ panY: () => number;
+ zoomScaling: () => number;
+ easing: () => boolean;
+}
- return (
- <Measure onResize={(r: any) => runInAction(() => { this._pwidth = r.entry.width; this._pheight = r.entry.height })}>
- {({ measureRef }) => (
- <div className={`collectionfreeformview-measure`} ref={measureRef}>
- <div className={`collectionfreeformview${this.isAnnotationOverlay ? "-overlay" : "-container"}`}
- onPointerDown={this.onPointerDown} onPointerMove={(e) => super.setCursorPosition(this.getTransform().transformPoint(e.clientX, e.clientY))}
- onDrop={this.onDrop.bind(this)} onDragOver={this.onDragOver} onWheel={this.onPointerWheel}
- style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} ref={this.createDropTarget}>
- <MarqueeView container={this} activeDocuments={this.getActiveDocuments} selectDocuments={this.selectDocuments}
- addDocument={this.addDocument} removeDocument={this.props.removeDocument}
- getContainerTransform={this.getContainerTransform} getTransform={this.getTransform}>
- <PreviewCursor container={this} addLiveTextDocument={this.addLiveTextBox}
- getContainerTransform={this.getContainerTransform} getTransform={this.getTransform} >
- <div className={freeformclass} ref={this._canvasRef}
- style={{ transform: `translate(${dx}px, ${dy}px) scale(${this.zoomScaling}, ${this.zoomScaling}) translate(${panx}px, ${pany}px)` }}>
- {this.backgroundView}
- <CollectionFreeFormLinksView {...this.props}>
- <InkingCanvas getScreenTransform={this.getTransform} Document={this.props.Document} >
- {this.childViews}
- </InkingCanvas>
- </CollectionFreeFormLinksView>
- <CollectionFreeFormRemoteCursors {...this.props} />
- </div>
- {this.overlayView}
- </PreviewCursor>
- </MarqueeView>
- </div>
- </div>)}
- </Measure>
- );
+@observer
+class CollectionFreeFormViewPannableContents extends React.Component<CollectionFreeFormViewPannableContentsProps>{
+ render() {
+ let freeformclass = "collectionfreeformview" + (this.props.easing() ? "-ease" : "-none");
+ const cenx = this.props.centeringShiftX();
+ const ceny = this.props.centeringShiftY();
+ const panx = -this.props.panX();
+ const pany = -this.props.panY();
+ const zoom = this.props.zoomScaling();// needs to be a variable outside of the <Measure> otherwise, reactions won't fire
+ return <div className={freeformclass} style={{ borderRadius: "inherit", transform: `translate(${cenx}px, ${ceny}px) scale(${zoom}, ${zoom}) translate(${panx}px, ${pany}px)` }}>
+ {this.props.children}
+ </div>;
}
} \ No newline at end of file