From 11134bc5ce01d0a025d311a4f83e67ff6e63ce1c Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Sat, 9 Feb 2019 19:13:24 -0500 Subject: Moved client code to client folder --- .../views/collections/CollectionFreeFormView.tsx | 205 +++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 src/client/views/collections/CollectionFreeFormView.tsx (limited to 'src/client/views/collections/CollectionFreeFormView.tsx') diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx new file mode 100644 index 000000000..9cf29d000 --- /dev/null +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -0,0 +1,205 @@ +import { observer } from "mobx-react"; +import React = require("react"); +import { action, observable, computed } from "mobx"; +import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; +import { DragManager } from "../../util/DragManager"; +import "./CollectionFreeFormView.scss"; +import { Utils } from "../../../Utils"; +import { CollectionViewBase, CollectionViewProps, COLLECTION_BORDER_WIDTH } from "./CollectionViewBase"; +import { SelectionManager } from "../../util/SelectionManager"; +import { Key, KeyStore } from "../../../fields/Key"; +import { Document } from "../../../fields/Document"; +import { ListField } from "../../../fields/ListField"; +import { NumberField } from "../../../fields/NumberField"; +import { Documents } from "../../documents/Documents"; +import { FieldWaiting } from "../../../fields/Field"; + +@observer +export class CollectionFreeFormView extends CollectionViewBase { + public static LayoutString() { return CollectionViewBase.LayoutString("CollectionFreeFormView"); } + private _containerRef = React.createRef(); + private _canvasRef = React.createRef(); + private _nodeContainerRef = React.createRef(); + private _lastX: number = 0; + private _lastY: number = 0; + + constructor(props: CollectionViewProps) { + super(props); + } + + @action + drop = (e: Event, de: DragManager.DropEvent) => { + const doc = 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 { scale, translateX, translateY } = Utils.GetScreenTransform(this._canvasRef.current!); + let sscale = this.props.ContainingDocumentView!.props.Document.GetData(KeyStore.Scale, NumberField, Number(1)) + const screenX = de.x - xOffset; + const screenY = de.y - yOffset; + const docX = (screenX - translateX) / sscale / scale; + const docY = (screenY - translateY) / sscale / scale; + doc.x = docX; + doc.y = docY; + this.bringToFront(doc); + } + e.stopPropagation(); + } + + componentDidMount() { + if (this._containerRef.current) { + DragManager.MakeDropTarget(this._containerRef.current, { + handlers: { + drop: this.drop + } + }); + } + } + + @action + onPointerDown = (e: React.PointerEvent): void => { + if ((e.button === 2 && this.active) || + !e.defaultPrevented) { + document.removeEventListener("pointermove", this.onPointerMove); + document.addEventListener("pointermove", this.onPointerMove); + document.removeEventListener("pointerup", this.onPointerUp); + document.addEventListener("pointerup", this.onPointerUp); + this._lastX = e.pageX; + this._lastY = e.pageY; + } + } + + @action + onPointerUp = (e: PointerEvent): void => { + document.removeEventListener("pointermove", this.onPointerMove); + document.removeEventListener("pointerup", this.onPointerUp); + e.stopPropagation(); + SelectionManager.DeselectAll(); + } + + @action + onPointerMove = (e: PointerEvent): void => { + var me = this; + if (!e.cancelBubble && this.active) { + e.preventDefault(); + e.stopPropagation(); + let currScale: number = this.props.ContainingDocumentView!.ScalingToScreenSpace; + let x = this.props.DocumentForCollection.GetData(KeyStore.PanX, NumberField, Number(0)); + let y = this.props.DocumentForCollection.GetData(KeyStore.PanY, NumberField, Number(0)); + this.props.DocumentForCollection.SetData(KeyStore.PanX, x + (e.pageX - this._lastX) / currScale, NumberField); + this.props.DocumentForCollection.SetData(KeyStore.PanY, y + (e.pageY - this._lastY) / currScale, NumberField); + } + this._lastX = e.pageX; + this._lastY = e.pageY; + } + + @action + onPointerWheel = (e: React.WheelEvent): void => { + e.stopPropagation(); + + let { LocalX, Ss, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY } = this.props.ContainingDocumentView!.TransformToLocalPoint(e.pageX, e.pageY); + + var deltaScale = (1 - (e.deltaY / 1000)) * Ss; + + var newContainerX = LocalX * deltaScale + Panxx + Xx; + var newContainerY = LocalY * deltaScale + Panyy + Yy; + + let dx = ContainerX - newContainerX; + let dy = ContainerY - newContainerY; + + this.props.DocumentForCollection.Set(KeyStore.Scale, new NumberField(deltaScale)); + this.props.DocumentForCollection.SetData(KeyStore.PanX, Panxx + dx, NumberField); + this.props.DocumentForCollection.SetData(KeyStore.PanY, Panyy + dy, NumberField); + } + + @action + onDrop = (e: React.DragEvent): void => { + e.stopPropagation() + e.preventDefault() + let fReader = new FileReader() + let file = e.dataTransfer.items[0].getAsFile(); + let that = this; + const panx: number = this.props.DocumentForCollection.GetData(KeyStore.PanX, NumberField, Number(0)); + const pany: number = this.props.DocumentForCollection.GetData(KeyStore.PanY, NumberField, Number(0)); + let x = e.pageX - panx + let y = e.pageY - pany + + fReader.addEventListener("load", action("drop", (event) => { + if (fReader.result) { + let url = "" + fReader.result; + let doc = Documents.ImageDocument(url, { + x: x, y: y + }) + let docs = that.props.DocumentForCollection.GetT(KeyStore.Data, ListField); + if (docs != FieldWaiting) { + if (!docs) { + docs = new ListField(); + that.props.DocumentForCollection.Set(KeyStore.Data, docs) + } + docs.Data.push(doc); + } + } + }), false) + + if (file) { + fReader.readAsDataURL(file) + } + } + + onDragOver = (e: React.DragEvent): void => { + } + + @action + bringToFront(doc: CollectionFreeFormDocumentView) { + const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; + + const value: Document[] = Document.GetList(fieldKey, []); + var topmost = value.reduce((topmost, d) => Math.max(d.GetNumber(KeyStore.ZIndex, 0), topmost), -1000); + value.map(d => { + var zind = d.GetNumber(KeyStore.ZIndex, 0); + if (zind != topmost - 1 - (topmost - zind) && d != doc.props.Document) { + d.SetData(KeyStore.ZIndex, topmost - 1 - (topmost - zind), NumberField); + } + }) + + if (doc.props.Document.GetNumber(KeyStore.ZIndex, 0) != 0) { + doc.props.Document.SetData(KeyStore.ZIndex, 0, NumberField); + } + } + + render() { + const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; + const value: Document[] = Document.GetList(fieldKey, []); + const panx: number = Document.GetNumber(KeyStore.PanX, 0); + const pany: number = Document.GetNumber(KeyStore.PanY, 0); + const currScale: number = Document.GetNumber(KeyStore.Scale, 1); + + return ( +
+
e.preventDefault()} + onDrop={this.onDrop} + onDragOver={this.onDragOver} + ref={this._containerRef}> +
+ +
+ {value.map(doc => { + return (); + })} +
+
+
+
+ ); + } +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 9f8653ab3d7f82a5d82b925bf339bef8d6723f5c Mon Sep 17 00:00:00 2001 From: bob Date: Mon, 11 Feb 2019 17:37:03 -0500 Subject: added framework for annotation overlays -- see ImageBox --- src/client/documents/Documents.ts | 14 +++-- src/client/views/Main.tsx | 12 ++-- .../views/collections/CollectionDockingView.tsx | 4 +- .../views/collections/CollectionFreeFormView.tsx | 69 ++++++++++++++-------- .../views/collections/CollectionSchemaView.tsx | 14 +++-- .../views/collections/CollectionViewBase.tsx | 1 + .../views/nodes/CollectionFreeFormDocumentView.tsx | 3 +- src/client/views/nodes/DocumentView.tsx | 20 ++++++- src/client/views/nodes/ImageBox.scss | 1 + src/client/views/nodes/ImageBox.tsx | 10 +++- src/fields/Key.ts | 3 + 11 files changed, 101 insertions(+), 50 deletions(-) (limited to 'src/client/views/collections/CollectionFreeFormView.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 6925234fe..12eddaec9 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -115,11 +115,13 @@ export namespace Documents { imageProto.Set(KeyStore.Title, new TextField("IMAGE PROTO")); imageProto.Set(KeyStore.X, new NumberField(0)); imageProto.Set(KeyStore.Y, new NumberField(0)); - imageProto.Set(KeyStore.Width, new NumberField(300)); - imageProto.Set(KeyStore.Height, new NumberField(300)); - imageProto.Set(KeyStore.Layout, new TextField(ImageBox.LayoutString())); + imageProto.Set(KeyStore.NativeWidth, new NumberField(606)); + imageProto.Set(KeyStore.Width, new NumberField(606)); + imageProto.Set(KeyStore.Height, new NumberField(446)); + imageProto.Set(KeyStore.Layout, new TextField("")); + imageProto.Set(KeyStore.AnnotatedLayout, new TextField(ImageBox.LayoutString())); // imageProto.SetField(KeyStore.Layout, new TextField('
')); - imageProto.Set(KeyStore.LayoutKeys, new ListField([KeyStore.Data])); + imageProto.Set(KeyStore.LayoutKeys, new ListField([KeyStore.Data, KeyStore.Annotations])); Server.AddDocument(imageProto); return imageProto; } @@ -130,6 +132,10 @@ export namespace Documents { let doc = GetImagePrototype().MakeDelegate(); setupOptions(doc, options); doc.Set(KeyStore.Data, new ImageField(new URL(url))); + + let annotation = Documents.TextDocument({ title: "hello" }); + Server.AddDocument(annotation); + doc.Set(KeyStore.Annotations, new ListField([annotation])); Server.AddDocument(doc); var sdoc = Server.GetField(doc.Id) as Document; return sdoc; diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 9a359e868..31a709744 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -43,11 +43,11 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) { let doc2 = doc1.MakeDelegate(); doc2.Set(KS.X, new NumberField(150)); doc2.Set(KS.Y, new NumberField(20)); - let doc3 = Documents.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { + let doc3 = Documents.ImageDocument("https://psmag.com/.image/t_share/MTMyNzc2NzM1MDY1MjgzMDM4/shutterstock_151341212jpg.jpg", { x: 450, y: 100, title: "cat 1" }); - doc3.Set(KeyStore.Data, new ImageField); - const schemaDocs = Array.from(Array(5).keys()).map(v => Documents.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { + //doc3.Set(KeyStore.Data, new ImageField); + const schemaDocs = Array.from(Array(5).keys()).map(v => Documents.ImageDocument("https://psmag.com/.image/t_share/MTMyNzc2NzM1MDY1MjgzMDM4/shutterstock_151341212jpg.jpg", { x: 50 + 100 * v, y: 50, width: 100, height: 100, title: "cat" + v })); schemaDocs[0].SetData(KS.Author, "Tyler", TextField); @@ -61,7 +61,7 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) { // let doc5 = Documents.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { // x: 650, y: 500, width: 600, height: 600, title: "cat 2" // }); - let docset2 = new Array(doc4);//, doc1, doc3); + let docset2 = [doc4, doc1, doc3]; let doc6 = Documents.CollectionDocument(docset2, { x: 350, y: 100, width: 600, height: 600, title: "docking collection" }); @@ -76,7 +76,7 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) { // mainNodes.Data.push(doc5); // mainNodes.Data.push(doc1); //mainNodes.Data.push(doc2); - //mainNodes.Data.push(doc6); + mainNodes.Data.push(doc6); mainContainer.Set(KeyStore.Data, mainNodes); } //} @@ -84,7 +84,7 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) { ReactDOM.render((
- +
), diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 9aee9c10f..037b85712 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -95,7 +95,7 @@ export class CollectionDockingView extends CollectionViewBase { const value: Document[] = Document.GetData(fieldKey, ListField, []); for (var i: number = 0; i < value.length; i++) { if (value[i].Id === component) { - return (); + return (); } } if (component === "text") { @@ -236,7 +236,7 @@ export class CollectionDockingView extends CollectionViewBase { container.getElement().html("
"); setTimeout(function () { ReactDOM.render(( - + ), document.getElementById(containingDiv) ); diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 9cf29d000..9cf8f2e35 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -22,11 +22,25 @@ export class CollectionFreeFormView extends CollectionViewBase { private _nodeContainerRef = React.createRef(); private _lastX: number = 0; private _lastY: number = 0; + private _downX: number = 0; + private _downY: number = 0; constructor(props: CollectionViewProps) { super(props); } + @computed + get isAnnotationOverlay() { return this.props.CollectionFieldKey == KeyStore.Annotations; } + + @computed + get nativeWidth() { return this.props.DocumentForCollection.GetNumber(KeyStore.NativeWidth, 0); } + + @computed + get zoomScaling() { return this.props.DocumentForCollection.GetNumber(KeyStore.Scale, 1); } + + @computed + get resizeScaling() { return this.isAnnotationOverlay ? this.props.DocumentForCollection.GetNumber(KeyStore.Width, 0) / this.nativeWidth : 1; } + @action drop = (e: Event, de: DragManager.DropEvent) => { const doc = de.data["document"]; @@ -38,12 +52,12 @@ export class CollectionFreeFormView extends CollectionViewBase { } const xOffset = de.data["xOffset"] as number || 0; const yOffset = de.data["yOffset"] as number || 0; - const { scale, translateX, translateY } = Utils.GetScreenTransform(this._canvasRef.current!); - let sscale = this.props.ContainingDocumentView!.props.Document.GetData(KeyStore.Scale, NumberField, Number(1)) + 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; - const docX = (screenX - translateX) / sscale / scale; - const docY = (screenY - translateY) / sscale / scale; + const docX = (screenX - translateX) / currScale; + const docY = (screenY - translateY) / currScale; doc.x = docX; doc.y = docY; this.bringToFront(doc); @@ -69,8 +83,8 @@ export class CollectionFreeFormView extends CollectionViewBase { document.addEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); document.addEventListener("pointerup", this.onPointerUp); - this._lastX = e.pageX; - this._lastY = e.pageY; + this._downX = this._lastX = e.pageX; + this._downY = this._lastY = e.pageY; } } @@ -79,20 +93,23 @@ export class CollectionFreeFormView extends CollectionViewBase { document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); e.stopPropagation(); - SelectionManager.DeselectAll(); + 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); + } + } } @action onPointerMove = (e: PointerEvent): void => { - var me = this; if (!e.cancelBubble && this.active) { e.preventDefault(); e.stopPropagation(); let currScale: number = this.props.ContainingDocumentView!.ScalingToScreenSpace; - let x = this.props.DocumentForCollection.GetData(KeyStore.PanX, NumberField, Number(0)); - let y = this.props.DocumentForCollection.GetData(KeyStore.PanY, NumberField, Number(0)); - this.props.DocumentForCollection.SetData(KeyStore.PanX, x + (e.pageX - this._lastX) / currScale, NumberField); - this.props.DocumentForCollection.SetData(KeyStore.PanY, y + (e.pageY - this._lastY) / currScale, NumberField); + let x = this.props.DocumentForCollection.GetNumber(KeyStore.PanX, 0); + let y = this.props.DocumentForCollection.GetNumber(KeyStore.PanY, 0); + + this.SetPan(x + (e.pageX - this._lastX) / currScale, y + (e.pageY - this._lastY) / currScale); } this._lastX = e.pageX; this._lastY = e.pageY; @@ -105,16 +122,18 @@ export class CollectionFreeFormView extends CollectionViewBase { let { LocalX, Ss, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY } = this.props.ContainingDocumentView!.TransformToLocalPoint(e.pageX, e.pageY); var deltaScale = (1 - (e.deltaY / 1000)) * Ss; + var newDeltaScale = this.isAnnotationOverlay ? Math.max(1, deltaScale) : deltaScale; - var newContainerX = LocalX * deltaScale + Panxx + Xx; - var newContainerY = LocalY * deltaScale + Panyy + Yy; - - let dx = ContainerX - newContainerX; - let dy = ContainerY - newContainerY; + this.props.DocumentForCollection.SetNumber(KeyStore.Scale, newDeltaScale); + this.SetPan(ContainerX - (LocalX * newDeltaScale + Xx), ContainerY - (LocalY * newDeltaScale + Yy)); + } - this.props.DocumentForCollection.Set(KeyStore.Scale, new NumberField(deltaScale)); - this.props.DocumentForCollection.SetData(KeyStore.PanX, Panxx + dx, NumberField); - this.props.DocumentForCollection.SetData(KeyStore.PanY, Panyy + dy, NumberField); + @action + private SetPan(panX: number, panY: number) { + const newPanX = Math.max(-(this.resizeScaling * this.zoomScaling - this.resizeScaling) * this.nativeWidth, Math.min(0, panX)); + const newPanY = Math.min(0, panY); + this.props.DocumentForCollection.SetNumber(KeyStore.PanX, this.isAnnotationOverlay ? newPanX : panX); + this.props.DocumentForCollection.SetNumber(KeyStore.PanY, this.isAnnotationOverlay ? newPanY : panY); } @action @@ -173,11 +192,10 @@ export class CollectionFreeFormView extends CollectionViewBase { } render() { - const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; - const value: Document[] = Document.GetList(fieldKey, []); + const Document: Document = this.props.DocumentForCollection; + const value: Document[] = Document.GetList(this.props.CollectionFieldKey, []); const panx: number = Document.GetNumber(KeyStore.PanX, 0); const pany: number = Document.GetNumber(KeyStore.PanY, 0); - const currScale: number = Document.GetNumber(KeyStore.Scale, 1); return (
-
+
+ {this.props.BackgroundView} {value.map(doc => { - return (); + return (); })}
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 2d5bd6c99..b2ee2f5f2 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -86,10 +86,11 @@ export class CollectionSchemaView extends CollectionViewBase { if (target.tagName == "SPAN" && target.className.includes("Resizer")) { e.stopPropagation(); } - if (e.button === 2 && this.active) { - e.stopPropagation(); - e.preventDefault(); - } else { + // if (e.button === 2 && this.active) { + // e.stopPropagation(); + // e.preventDefault(); + // } else + { if (e.buttons === 1 && this.active) { e.stopPropagation(); } @@ -104,7 +105,7 @@ export class CollectionSchemaView extends CollectionViewBase { let content; if (this.selectedIndex != -1) { content = ( - + ) } else { content =
@@ -119,7 +120,8 @@ export class CollectionSchemaView extends CollectionViewBase { page={0} showPagination={false} style={{ - display: "inline-block" + display: "inline-block", + width: "100%" }} columns={columns.map(col => { return ( diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx index 09e8ec729..e854d3077 100644 --- a/src/client/views/collections/CollectionViewBase.tsx +++ b/src/client/views/collections/CollectionViewBase.tsx @@ -16,6 +16,7 @@ export interface CollectionViewProps { CollectionFieldKey: Key; DocumentForCollection: Document; ContainingDocumentView: Opt; + BackgroundView: Opt; } export const COLLECTION_BORDER_WIDTH = 2; diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 1d53cedc4..a183db828 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -48,7 +48,7 @@ export class CollectionFreeFormDocumentView extends DocumentView { @computed get transform(): string { - return `translate(${this.x}px, ${this.y}px)`; + return `scale(${this.props.Scaling}, ${this.props.Scaling}) translate(${this.x}px, ${this.y}px)`; } @computed @@ -207,6 +207,7 @@ export class CollectionFreeFormDocumentView extends DocumentView { var freestyling = this.props.ContainingCollectionView instanceof CollectionFreeFormView; return (
// needed only to set ContainingDocumentView on CollectionViewProps when invoked from JsxParser -- is there a better way? ContainingCollectionView: Opt; + Scaling: number; } @observer export class DocumentView extends React.Component { @@ -34,6 +35,11 @@ export class DocumentView extends React.Component { return this.props.Document.GetData(KeyStore.Layout, TextField, String("

Error loading layout data

")); } + @computed + get annotatedlayout(): string { + return this.props.Document.GetData(KeyStore.AnnotatedLayout, TextField, String("

Error loading layout data

")); + } + @computed get layoutKeys(): Key[] { return this.props.Document.GetData(KeyStore.LayoutKeys, ListField, new Array()); @@ -51,7 +57,7 @@ export class DocumentView extends React.Component { public get ScalingToScreenSpace(): number { if (this.props.ContainingCollectionView != undefined && this.props.ContainingCollectionView.props.ContainingDocumentView != undefined) { - let ss = this.props.ContainingCollectionView.props.DocumentForCollection.GetData(KeyStore.Scale, NumberField, Number(1)); + let ss = this.props.ContainingCollectionView.props.DocumentForCollection.GetNumber(KeyStore.Scale, 1); return this.props.ContainingCollectionView.props.ContainingDocumentView.ScalingToScreenSpace * ss; } return 1; @@ -81,7 +87,7 @@ export class DocumentView extends React.Component { Yy = ry - COLLECTION_BORDER_WIDTH; } - let Ss = this.props.Document.GetData(KeyStore.Scale, NumberField, Number(1)); + 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; @@ -115,7 +121,7 @@ export class DocumentView extends React.Component { // 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.GetData(KeyStore.Scale, NumberField, Number(1)); + 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); @@ -138,6 +144,14 @@ export class DocumentView extends React.Component { 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 = { console.log(test) }} + />; + bindings["BackgroundView"] = this.annotatedlayout ? annotated : null; return (
{ @@ -67,7 +68,9 @@ export class ImageBox extends React.Component { mainSrc={images[this._photoIndex]} nextSrc={images[(this._photoIndex + 1) % images.length]} prevSrc={images[(this._photoIndex + images.length - 1) % images.length]} - onCloseRequest={() => this.setState({ isOpen: false })} + onCloseRequest={action(() => + this._isOpen = false + )} onMovePrevRequest={action(() => this._photoIndex = (this._photoIndex + images.length - 1) % images.length )} @@ -82,10 +85,11 @@ export class ImageBox extends React.Component { 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); return (
- Image not found + Image not found {this.lightbox(path)}
) } diff --git a/src/fields/Key.ts b/src/fields/Key.ts index 993102613..67a5f86fb 100644 --- a/src/fields/Key.ts +++ b/src/fields/Key.ts @@ -42,11 +42,14 @@ export namespace KeyStore { export const PanX = new Key("PanX"); export const PanY = new Key("PanY"); export const Scale = new Key("Scale"); + export const NativeWidth = new Key("NativeWidth"); export const Width = new Key("Width"); export const Height = new Key("Height"); export const ZIndex = new Key("ZIndex"); export const Data = new Key("Data"); + export const Annotations = new Key("Annotations"); export const Layout = new Key("Layout"); + export const AnnotatedLayout = new Key("AnnotatedLayout"); export const LayoutKeys = new Key("LayoutKeys"); export const LayoutFields = new Key("LayoutFields"); export const ColumnsKey = new Key("SchemaColumns"); -- cgit v1.2.3-70-g09d2 From 793cc99ab134bc5aa4667c95def851ce08d35146 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 11 Feb 2019 21:17:24 -0500 Subject: added aspect resizing. fixed pinch zoom for macs --- src/client/documents/Documents.ts | 15 ++++++++++++--- src/client/views/DocumentDecorations.tsx | 6 ++++-- src/client/views/Main.tsx | 4 ++-- .../views/collections/CollectionFreeFormView.tsx | 17 +++++++++++------ .../views/nodes/CollectionFreeFormDocumentView.tsx | 21 ++++++++++++++++++--- src/fields/Key.ts | 1 + 6 files changed, 48 insertions(+), 16 deletions(-) (limited to 'src/client/views/collections/CollectionFreeFormView.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 12eddaec9..84aaaa78f 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -17,6 +17,8 @@ interface DocumentOptions { y?: number; width?: number; height?: number; + nativeWidth?: number; + nativeHeight?: number; title?: string; } @@ -34,6 +36,12 @@ export namespace Documents { if (options.height) { doc.SetData(KeyStore.Height, options.height, NumberField); } + if (options.nativeWidth) { + doc.SetData(KeyStore.NativeWidth, options.nativeWidth, NumberField); + } + if (options.nativeHeight) { + doc.SetData(KeyStore.NativeHeight, options.nativeHeight, NumberField); + } if (options.title) { doc.SetData(KeyStore.Title, options.title, TextField); } @@ -115,9 +123,10 @@ export namespace Documents { imageProto.Set(KeyStore.Title, new TextField("IMAGE PROTO")); imageProto.Set(KeyStore.X, new NumberField(0)); imageProto.Set(KeyStore.Y, new NumberField(0)); - imageProto.Set(KeyStore.NativeWidth, new NumberField(606)); - imageProto.Set(KeyStore.Width, new NumberField(606)); - imageProto.Set(KeyStore.Height, new NumberField(446)); + imageProto.Set(KeyStore.NativeWidth, new NumberField(300)); + imageProto.Set(KeyStore.NativeHeight, new NumberField(300)); + imageProto.Set(KeyStore.Width, new NumberField(300)); + imageProto.Set(KeyStore.Height, new NumberField(300)); imageProto.Set(KeyStore.Layout, new TextField("")); imageProto.Set(KeyStore.AnnotatedLayout, new TextField(ImageBox.LayoutString())); // imageProto.SetField(KeyStore.Layout, new TextField('
')); diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 8a94bff36..7efaa5533 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -111,8 +111,10 @@ export class DocumentDecorations extends React.Component { let actualdH = Math.max(element.height + (dH * scale), 20); element.x += dX * (actualdW - element.width); element.y += dY * (actualdH - element.height); - element.width = actualdW; - element.height = actualdH; + if (Math.abs(dW) > Math.abs(dH)) + element.width = actualdW; + else + element.height = actualdH; } }) } diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 31a709744..8d474698f 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -44,11 +44,11 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) { doc2.Set(KS.X, new NumberField(150)); doc2.Set(KS.Y, new NumberField(20)); let doc3 = Documents.ImageDocument("https://psmag.com/.image/t_share/MTMyNzc2NzM1MDY1MjgzMDM4/shutterstock_151341212jpg.jpg", { - x: 450, y: 100, title: "cat 1" + x: 450, y: 100, title: "cat 1", width: 606, height: 386, nativeWidth: 606, nativeHeight: 386 }); //doc3.Set(KeyStore.Data, new ImageField); const schemaDocs = Array.from(Array(5).keys()).map(v => Documents.ImageDocument("https://psmag.com/.image/t_share/MTMyNzc2NzM1MDY1MjgzMDM4/shutterstock_151341212jpg.jpg", { - x: 50 + 100 * v, y: 50, width: 100, height: 100, title: "cat" + v + x: 50 + 100 * v, y: 50, width: 100, height: 100, title: "cat" + v, nativeWidth: 606, nativeHeight: 386 })); schemaDocs[0].SetData(KS.Author, "Tyler", TextField); schemaDocs[4].SetData(KS.Author, "Bob", TextField); diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 9cf8f2e35..bf24965dc 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -34,6 +34,8 @@ export class CollectionFreeFormView extends CollectionViewBase { @computed get nativeWidth() { return this.props.DocumentForCollection.GetNumber(KeyStore.NativeWidth, 0); } + @computed + get nativeHeight() { return this.props.DocumentForCollection.GetNumber(KeyStore.NativeHeight, 0); } @computed get zoomScaling() { return this.props.DocumentForCollection.GetNumber(KeyStore.Scale, 1); } @@ -56,10 +58,8 @@ export class CollectionFreeFormView extends CollectionViewBase { const currScale = this.resizeScaling * this.zoomScaling * this.props.ContainingDocumentView!.ScalingToScreenSpace; const screenX = de.x - xOffset; const screenY = de.y - yOffset; - const docX = (screenX - translateX) / currScale; - const docY = (screenY - translateY) / currScale; - doc.x = docX; - doc.y = docY; + doc.x = (screenX - translateX) / currScale; + doc.y = (screenY - translateY) / currScale; this.bringToFront(doc); } e.stopPropagation(); @@ -118,10 +118,15 @@ export class CollectionFreeFormView extends CollectionViewBase { @action onPointerWheel = (e: React.WheelEvent): void => { e.stopPropagation(); + e.preventDefault(); + let modes = ['pixels', 'lines', 'page']; + 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 { LocalX, Ss, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY } = this.props.ContainingDocumentView!.TransformToLocalPoint(e.pageX, e.pageY); - var deltaScale = (1 - (e.deltaY / 1000)) * Ss; + var deltaScale = (1 - (e.deltaY / coefficient)) * Ss; var newDeltaScale = this.isAnnotationOverlay ? Math.max(1, deltaScale) : deltaScale; this.props.DocumentForCollection.SetNumber(KeyStore.Scale, newDeltaScale); @@ -131,7 +136,7 @@ export class CollectionFreeFormView extends CollectionViewBase { @action private SetPan(panX: number, panY: number) { const newPanX = Math.max(-(this.resizeScaling * this.zoomScaling - this.resizeScaling) * this.nativeWidth, Math.min(0, panX)); - const newPanY = Math.min(0, panY); + const newPanY = Math.max(-(this.resizeScaling * this.zoomScaling - this.resizeScaling) * this.nativeHeight, Math.min(0, panY)); this.props.DocumentForCollection.SetNumber(KeyStore.PanX, this.isAnnotationOverlay ? newPanX : panX); this.props.DocumentForCollection.SetNumber(KeyStore.PanY, this.isAnnotationOverlay ? newPanY : panY); } diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index a183db828..fafb470f9 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -53,20 +53,35 @@ export class CollectionFreeFormDocumentView extends DocumentView { @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 diff --git a/src/fields/Key.ts b/src/fields/Key.ts index 67a5f86fb..13bdd01d4 100644 --- a/src/fields/Key.ts +++ b/src/fields/Key.ts @@ -43,6 +43,7 @@ export namespace KeyStore { export const PanY = new Key("PanY"); export const Scale = new Key("Scale"); export const NativeWidth = new Key("NativeWidth"); + export const NativeHeight = new Key("NativeHeight"); export const Width = new Key("Width"); export const Height = new Key("Height"); export const ZIndex = new Key("ZIndex"); -- cgit v1.2.3-70-g09d2 From e2ca8fa7ec95768ef37914b909ee47fbca6b1251 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Tue, 12 Feb 2019 00:44:01 -0500 Subject: Added transforms to everything, not being used yet --- package-lock.json | 199 ++++++++++++++++++++- package.json | 1 + src/client/util/Transform.ts | 94 ++++++++++ src/client/views/Main.tsx | 5 +- .../views/collections/CollectionDockingView.tsx | 11 +- .../views/collections/CollectionFreeFormView.tsx | 24 ++- .../views/collections/CollectionSchemaView.tsx | 6 +- .../views/collections/CollectionViewBase.tsx | 11 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 7 +- src/client/views/nodes/DocumentView.tsx | 8 +- 10 files changed, 354 insertions(+), 12 deletions(-) create mode 100644 src/client/util/Transform.ts (limited to 'src/client/views/collections/CollectionFreeFormView.tsx') diff --git a/package-lock.json b/package-lock.json index 535c348d5..a4939f1cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -684,6 +684,11 @@ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -745,6 +750,11 @@ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" }, + "ast-types": { + "version": "0.9.6", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.6.tgz", + "integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=" + }, "async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", @@ -883,6 +893,11 @@ } } }, + "base62": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/base62/-/base62-1.2.8.tgz", + "integrity": "sha512-V6YHUbjLxN1ymqNLb1DPHoU1CpfdL7d2YTIp5W3U4hhoG4hhxNmsFDs66M9EXxBiSEke5Bt5dwdfMwwZF70iLA==" + }, "base64-js": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", @@ -1445,8 +1460,7 @@ "commander": { "version": "2.15.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" }, "commondir": { "version": "1.0.1", @@ -1454,6 +1468,36 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, + "commoner": { + "version": "0.10.8", + "resolved": "https://registry.npmjs.org/commoner/-/commoner-0.10.8.tgz", + "integrity": "sha1-NPw2cs0kOT6LtH5wyqApOBH08sU=", + "requires": { + "commander": "^2.5.0", + "detective": "^4.3.1", + "glob": "^5.0.15", + "graceful-fs": "^4.1.2", + "iconv-lite": "^0.4.5", + "mkdirp": "^0.5.0", + "private": "^0.1.6", + "q": "^1.1.2", + "recast": "^0.11.17" + }, + "dependencies": { + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, "component-emitter": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", @@ -1594,6 +1638,11 @@ "serialize-javascript": "^1.4.0" } }, + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -1884,6 +1933,11 @@ } } }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" + }, "del": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", @@ -1969,6 +2023,15 @@ "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", "dev": true }, + "detective": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz", + "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==", + "requires": { + "acorn": "^5.2.1", + "defined": "^1.0.0" + } + }, "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", @@ -2127,6 +2190,15 @@ "tapable": "^1.0.0" } }, + "envify": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/envify/-/envify-3.4.1.tgz", + "integrity": "sha1-1xIjKejfFoi6dxsSUBkXyc5cvOg=", + "requires": { + "jstransform": "^11.0.3", + "through": "~2.3.4" + } + }, "errno": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", @@ -2196,6 +2268,11 @@ "estraverse": "^4.1.1" } }, + "esprima-fb": { + "version": "15001.1.0-dev-harmony-fb", + "resolved": "https://registry.npmjs.org/esprima-fb/-/esprima-fb-15001.1.0-dev-harmony-fb.tgz", + "integrity": "sha1-MKlHMDxrjV6VW+4rmbHSMyBqaQE=" + }, "esrecurse": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", @@ -2479,6 +2556,18 @@ "websocket-driver": ">=0.5.1" } }, + "fbjs": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.6.1.tgz", + "integrity": "sha1-lja3cF9bqWhNRLcveDISVK/IYPc=", + "requires": { + "core-js": "^1.0.0", + "loose-envify": "^1.0.0", + "promise": "^7.0.3", + "ua-parser-js": "^0.7.9", + "whatwg-fetch": "^0.9.0" + } + }, "figgy-pudding": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", @@ -3649,6 +3738,11 @@ "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=" }, + "immutable": { + "version": "4.0.0-rc.12", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0-rc.12.tgz", + "integrity": "sha512-0M2XxkZLx/mi3t8NVwIm1g8nHoEmM9p9UBl/G9k4+hm0kBgOVdMV/B3CY5dQ8qG8qc80NN4gDV4HQv6FTJ5q7A==" + }, "import-lazy": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", @@ -4092,6 +4186,11 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, + "json-stringify-pretty-compact": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-1.2.0.tgz", + "integrity": "sha512-/11Pj1OyX814QMKO7K8l85SHPTr/KsFxHp8GE2zVa0BtJgGimDjXHfM3FhC7keQdWDea7+nXf+f1de7ATZcZkQ==" + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -4122,6 +4221,46 @@ "verror": "1.10.0" } }, + "jstransform": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/jstransform/-/jstransform-11.0.3.tgz", + "integrity": "sha1-CaeJk+CuTU70SH9hVakfYZDLQiM=", + "requires": { + "base62": "^1.1.0", + "commoner": "^0.10.1", + "esprima-fb": "^15001.1.0-dev-harmony-fb", + "object-assign": "^2.0.0", + "source-map": "^0.4.2" + }, + "dependencies": { + "object-assign": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", + "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=" + } + } + }, + "jsx-to-string": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jsx-to-string/-/jsx-to-string-1.4.0.tgz", + "integrity": "sha1-Ztw013PaufQP6ZPP+ZQOXaZVtwU=", + "requires": { + "immutable": "^4.0.0-rc.9", + "json-stringify-pretty-compact": "^1.0.1", + "react": "^0.14.0" + }, + "dependencies": { + "react": { + "version": "0.14.9", + "resolved": "https://registry.npmjs.org/react/-/react-0.14.9.tgz", + "integrity": "sha1-kRCmSXxJ1EuhwO3TF67CnC4NkdE=", + "requires": { + "envify": "^3.0.0", + "fbjs": "^0.6.1" + } + } + } + }, "killable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", @@ -8491,6 +8630,11 @@ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" + }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -8502,6 +8646,14 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "~2.0.3" + } + }, "promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", @@ -8659,6 +8811,11 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" + }, "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", @@ -8879,6 +9036,29 @@ "readable-stream": "^2.0.2" } }, + "recast": { + "version": "0.11.23", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.11.23.tgz", + "integrity": "sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM=", + "requires": { + "ast-types": "0.9.6", + "esprima": "~3.1.0", + "private": "~0.1.5", + "source-map": "~0.5.0" + }, + "dependencies": { + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, "redent": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", @@ -10075,6 +10255,11 @@ "native-promise-only": "^0.8.1" } }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, "through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", @@ -10263,6 +10448,11 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==" }, + "ua-parser-js": { + "version": "0.7.19", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.19.tgz", + "integrity": "sha512-T3PVJ6uz8i0HzPxOF9SWzWAlfN/DavlpQqepn22xgve/5QecC+XMCAtmUNnY7C9StehaV6exjUCI801lOI7QlQ==" + }, "undefsafe": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz", @@ -11238,6 +11428,11 @@ "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", "dev": true }, + "whatwg-fetch": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-0.9.0.tgz", + "integrity": "sha1-DjaExsuZlbQ+/J3wPkw2XZX9nMA=" + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", diff --git a/package.json b/package.json index 6697b5f47..657bb875d 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "express": "^4.16.4", "flexlayout-react": "^0.3.3", "golden-layout": "^1.5.9", + "jsx-to-string": "^1.4.0", "mobx": "^5.9.0", "mobx-react": "^5.3.5", "mobx-react-devtools": "^6.0.3", diff --git a/src/client/util/Transform.ts b/src/client/util/Transform.ts new file mode 100644 index 000000000..7861ed308 --- /dev/null +++ b/src/client/util/Transform.ts @@ -0,0 +1,94 @@ +export class Transform { + private _translateX: number = 0; + private _translateY: number = 0; + private _scale: number = 1; + + static get Identity(): Transform { + return new Transform(0, 0, 1); + } + + constructor(x: number, y: number, scale: number) { + this._translateX = x; + this._translateY = y; + this._scale = scale; + } + + translate = (x: number, y: number): Transform => { + this._translateX += x; + this._translateY += y; + 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; + return this; + } + + preTranslated = (x: number, y: number): Transform => { + return this.copy().preTranslate(x, y); + } + + scale = (scale: number): Transform => { + this._scale *= scale; + return this; + } + + scaled = (scale: number): Transform => { + return this.copy().scale(scale); + } + + 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 => { + 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); + } + + 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; + } + + preTransformed = (transform: Transform): Transform => { + return this.copy().preTransform(transform); + } + + transformPoint = (x: number, y: number): [number, number] => { + x *= this._scale; + x += this._translateX; + y *= this._scale; + y += this._translateY; + return [x, y]; + } + + inverse = () => { + return new Transform(-this._translateX / this._scale, -this._translateY / this._scale, 1 / this._scale) + } + + copy = () => { + return new Transform(this._translateX, this._translateY, this._scale); + } + +} \ No newline at end of file diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 9a359e868..ac6f1de00 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -13,6 +13,7 @@ import "./Main.scss"; import { ContextMenu } from './ContextMenu'; import { DocumentView } from './nodes/DocumentView'; import { ImageField } from '../../fields/ImageField'; +import { Transform } from '../util/Transform'; configure({ @@ -84,7 +85,9 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) { ReactDOM.render((
- + Transform.Identity} + ContainingCollectionView={undefined} DocumentView={undefined} />
), diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 9aee9c10f..32d00d41a 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -14,6 +14,7 @@ import * as GoldenLayout from "golden-layout"; import * as ReactDOM from 'react-dom'; import { DragManager } from "../../util/DragManager"; import { CollectionViewBase, CollectionViewProps, COLLECTION_BORDER_WIDTH } from "./CollectionViewBase"; +import { Transform } from "../../util/Transform"; @observer export class CollectionDockingView extends CollectionViewBase { @@ -95,7 +96,10 @@ export class CollectionDockingView extends CollectionViewBase { const value: Document[] = Document.GetData(fieldKey, ListField, []); for (var i: number = 0; i < value.length; i++) { if (value[i].Id === component) { - return (); + return ( Transform.Identity} + ContainingCollectionView={this} DocumentView={undefined} />); } } if (component === "text") { @@ -236,7 +240,10 @@ export class CollectionDockingView extends CollectionViewBase { container.getElement().html("
"); setTimeout(function () { ReactDOM.render(( - + Transform.Identity} + ContainingCollectionView={me} DocumentView={undefined} /> ), document.getElementById(containingDiv) ); diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 9cf29d000..50f4f1892 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -13,6 +13,7 @@ import { ListField } from "../../../fields/ListField"; import { NumberField } from "../../../fields/NumberField"; import { Documents } from "../../documents/Documents"; import { FieldWaiting } from "../../../fields/Field"; +import { Transform } from "../../util/Transform"; @observer export class CollectionFreeFormView extends CollectionViewBase { @@ -172,6 +173,23 @@ export class CollectionFreeFormView extends CollectionViewBase { } } + @computed + get translate(): [number, number] { + const x = this.props.DocumentForCollection.GetNumber(KeyStore.PanX, 0); + const y = this.props.DocumentForCollection.GetNumber(KeyStore.PanY, 0); + return [x, y]; + } + + @computed + get scale(): number { + return this.props.DocumentForCollection.GetNumber(KeyStore.Scale, 1); + } + + getTransform = (): Transform => { + const [x, y] = this.translate; + return this.props.GetTransform().scaled(this.scale).translate(x, y); + } + render() { const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; const value: Document[] = Document.GetList(fieldKey, []); @@ -194,7 +212,11 @@ export class CollectionFreeFormView extends CollectionViewBase {
{value.map(doc => { - return (); + return (); })}
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 2d5bd6c99..b897fd481 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -14,6 +14,7 @@ import { CompileScript, ToField } from "../../util/Scripting"; import { KeyStore as KS, Key } from "../../../fields/Key"; import { Document } from "../../../fields/Document"; import { Field } from "../../../fields/Field"; +import { Transform } from "../../util/Transform"; @observer export class CollectionSchemaView extends CollectionViewBase { @@ -104,7 +105,10 @@ export class CollectionSchemaView extends CollectionViewBase { let content; if (this.selectedIndex != -1) { content = ( - + Transform.Identity}//TODO This should probably be an actual transform + DocumentView={undefined} ContainingCollectionView={this} /> ) } else { content =
diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx index 09e8ec729..ff54d88d7 100644 --- a/src/client/views/collections/CollectionViewBase.tsx +++ b/src/client/views/collections/CollectionViewBase.tsx @@ -10,12 +10,14 @@ import React = require("react"); import { DocumentView } from "../nodes/DocumentView"; import { CollectionDockingView } from "./CollectionDockingView"; import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; +import { Transform } from "../../util/Transform"; export interface CollectionViewProps { CollectionFieldKey: Key; DocumentForCollection: Document; ContainingDocumentView: Opt; + GetTransform: () => Transform; } export const COLLECTION_BORDER_WIDTH = 2; @@ -43,15 +45,18 @@ export class CollectionViewBase extends React.Component { } @action - removeDocument = (doc: Document): void => { + removeDocument = (doc: Document): boolean => { //TODO This won't create the field if it doesn't already exist const value = this.props.DocumentForCollection.GetData(this.props.CollectionFieldKey, ListField, new Array()) - if (value.indexOf(doc) !== -1) { - value.splice(value.indexOf(doc), 1) + let index = value.indexOf(doc); + if (index !== -1) { + value.splice(index, 1) SelectionManager.DeselectAll() ContextMenu.Instance.clearItems() + return true; } + return false } } \ No newline at end of file diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index a111a9936..0defc8f1d 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -10,6 +10,7 @@ import { ContextMenu } from "../ContextMenu"; import "./NodeView.scss"; import React = require("react"); import { DocumentView, DocumentViewProps } from "./DocumentView"; +import { Transform } from "../../util/Transform"; @observer @@ -204,6 +205,10 @@ export class CollectionFreeFormDocumentView extends DocumentView { } } + getTransform = (): Transform => { + return this.props.GetTransform().translated(this.x, this.y); + } + render() { var freestyling = this.props.ContainingCollectionView instanceof CollectionFreeFormView; return ( @@ -217,7 +222,7 @@ export class CollectionFreeFormDocumentView extends DocumentView { onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown}> - +
); } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 730ce62f2..ce23a70a6 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -15,13 +15,19 @@ import { FormattedTextBox } from "../nodes/FormattedTextBox"; import { ImageBox } from "../nodes/ImageBox"; import "./NodeView.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 // needed only to set ContainingDocumentView on CollectionViewProps when invoked from JsxParser -- is there a better way? ContainingCollectionView: Opt; + + Document: Document; + AddDocument?: (doc: Document) => void; + RemoveDocument?: (doc: Document) => boolean; + GetTransform: () => Transform; } + @observer export class DocumentView extends React.Component { -- cgit v1.2.3-70-g09d2 From e1acd0061c45f680fee85f10e9187b9769022a40 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 12 Feb 2019 08:44:14 -0500 Subject: got rid of extra divs in collectionFreeFormView .... good idea or bad? --- .../views/collections/CollectionFreeFormView.scss | 9 +--- .../views/collections/CollectionFreeFormView.tsx | 48 +++++++++++----------- 2 files changed, 25 insertions(+), 32 deletions(-) (limited to 'src/client/views/collections/CollectionFreeFormView.tsx') diff --git a/src/client/views/collections/CollectionFreeFormView.scss b/src/client/views/collections/CollectionFreeFormView.scss index e9d134e7b..4cf474f77 100644 --- a/src/client/views/collections/CollectionFreeFormView.scss +++ b/src/client/views/collections/CollectionFreeFormView.scss @@ -1,4 +1,6 @@ .collectionfreeformview-container { + border-style: solid; + box-sizing: border-box; position: relative; top: 0; left: 0; @@ -10,11 +12,4 @@ top: 0; left: 0; } -} - -.border { - border-style: solid; - box-sizing: border-box; - width: 100%; - height: 100%; } \ No newline at end of file diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index e485c8e14..f767bbc16 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -20,7 +20,6 @@ export class CollectionFreeFormView extends CollectionViewBase { public static LayoutString() { return CollectionViewBase.LayoutString("CollectionFreeFormView"); } private _containerRef = React.createRef(); private _canvasRef = React.createRef(); - private _nodeContainerRef = React.createRef(); private _lastX: number = 0; private _lastY: number = 0; private _downX: number = 0; @@ -221,30 +220,29 @@ export class CollectionFreeFormView extends CollectionViewBase { const pany: number = Document.GetNumber(KeyStore.PanY, 0); return ( -
-
e.preventDefault()} - onDrop={this.onDrop} - onDragOver={this.onDragOver} - ref={this._containerRef}> -
- -
- {this.props.BackgroundView} - {value.map(doc => { - return (); - })} -
-
+
e.preventDefault()} + onDrop={this.onDrop} + onDragOver={this.onDragOver} + style={{ + borderWidth: `${COLLECTION_BORDER_WIDTH}px`, + }} + ref={this._containerRef}> +
+ + {this.props.BackgroundView} + {value.map(doc => { + return (); + })}
); -- cgit v1.2.3-70-g09d2 From 9dd25514bf0ede364e255e7f82d73369f6eb7f48 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 12 Feb 2019 10:29:23 -0500 Subject: apparently the mac pinch zoom vs scroll wheel detection doesn't work. --- src/client/views/collections/CollectionFreeFormView.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/client/views/collections/CollectionFreeFormView.tsx') diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index f767bbc16..2007a111b 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -121,8 +121,8 @@ export class CollectionFreeFormView extends CollectionViewBase { e.preventDefault(); let modes = ['pixels', 'lines', 'page']; let coefficient = 1000; - if (modes[e.deltaMode] == 'pixels') coefficient = 50; - else if (modes[e.deltaMode] == 'lines') coefficient = 1000; // This should correspond to line-height?? + // if (modes[e.deltaMode] == 'pixels') coefficient = 50; + // else if (modes[e.deltaMode] == 'lines') coefficient = 1000; // This should correspond to line-height?? let { LocalX, Ss, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY } = this.props.ContainingDocumentView!.TransformToLocalPoint(e.pageX, e.pageY); -- cgit v1.2.3-70-g09d2 From 2541c2cd562251143050554f3c0117caed6d9345 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 12 Feb 2019 10:48:03 -0500 Subject: still struggling with sizing issues. --- src/client/views/collections/CollectionDockingView.tsx | 5 +++-- src/client/views/collections/CollectionFreeFormView.tsx | 2 +- src/client/views/nodes/ImageBox.scss | 3 ++- src/client/views/nodes/ImageBox.tsx | 3 +-- 4 files changed, 7 insertions(+), 6 deletions(-) (limited to 'src/client/views/collections/CollectionFreeFormView.tsx') diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 15a586282..e3d50eb80 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -243,8 +243,9 @@ export class CollectionDockingView extends CollectionViewBase { setTimeout(function () { var htmlElement = document.getElementById(containingDiv); container.on('resize', (e: any) => { - state.doc.SetNumber(KeyStore.Width, htmlElement!.clientWidth); - state.doc.SetNumber(KeyStore.Height, htmlElement!.clientHeight); + // state.doc.SetNumber(KeyStore.Width, htmlElement!.clientWidth); + // if (htmlElement!.clientHeight > 0) + // state.doc.SetNumber(KeyStore.Height, htmlElement!.clientHeight); }) ReactDOM.render((
{this.props.BackgroundView} diff --git a/src/client/views/nodes/ImageBox.scss b/src/client/views/nodes/ImageBox.scss index 83392311b..2bd8b1d3c 100644 --- a/src/client/views/nodes/ImageBox.scss +++ b/src/client/views/nodes/ImageBox.scss @@ -1,7 +1,8 @@ .imageBox-cont { padding: 0vw; - position: absolute + position: absolute; + width: 100% } .imageBox-button { diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index b96e717ed..60be5f94d 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -85,11 +85,10 @@ export class ImageBox extends React.Component { 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); return (
- Image not found + Image not found {this.lightbox(path)}
) } -- cgit v1.2.3-70-g09d2 From 7a93f60c9529e5d175e617fc7c07145a9b33e572 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 12 Feb 2019 15:49:06 -0500 Subject: more updates to resizing, etc. --- src/client/documents/Documents.ts | 4 +- src/client/views/Main.tsx | 6 +-- .../views/collections/CollectionDockingView.tsx | 63 +++++++++++++++------- .../views/collections/CollectionFreeFormView.tsx | 7 +-- .../views/collections/CollectionSchemaView.tsx | 2 +- .../views/collections/CollectionViewBase.tsx | 5 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 9 +++- src/client/views/nodes/FormattedTextBox.tsx | 2 +- src/client/views/nodes/ImageBox.tsx | 3 +- 10 files changed, 68 insertions(+), 35 deletions(-) (limited to 'src/client/views/collections/CollectionFreeFormView.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 7512d25cb..72fa608ad 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -127,7 +127,7 @@ export namespace Documents { imageProto.Set(KeyStore.NativeHeight, new NumberField(300)); imageProto.Set(KeyStore.Width, new NumberField(300)); imageProto.Set(KeyStore.Height, new NumberField(300)); - imageProto.Set(KeyStore.Layout, new TextField("")); + imageProto.Set(KeyStore.Layout, new TextField(CollectionFreeFormView.LayoutString("AnnotationsKey"))); imageProto.Set(KeyStore.BackgroundLayout, new TextField(ImageBox.LayoutString())); // imageProto.SetField(KeyStore.Layout, new TextField('
')); imageProto.Set(KeyStore.LayoutKeys, new ListField([KeyStore.Data, KeyStore.Annotations])); @@ -161,7 +161,7 @@ export namespace Documents { collectionProto.Set(KeyStore.PanY, new NumberField(0)); collectionProto.Set(KeyStore.Width, new NumberField(300)); collectionProto.Set(KeyStore.Height, new NumberField(300)); - collectionProto.Set(KeyStore.Layout, new TextField(CollectionFreeFormView.LayoutString())); + collectionProto.Set(KeyStore.Layout, new TextField(CollectionFreeFormView.LayoutString("DataKey"))); collectionProto.Set(KeyStore.LayoutKeys, new ListField([KeyStore.Data])); } return collectionProto; diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index b58704264..ba92cc17e 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -40,7 +40,7 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) { //runInAction(() => { - let doc1 = Documents.TextDocument({ title: "hello" }); + let doc1 = Documents.TextDocument({ title: "hello", width: 400, height: 300 }); let doc2 = doc1.MakeDelegate(); doc2.Set(KS.X, new NumberField(150)); doc2.Set(KS.Y, new NumberField(20)); @@ -62,7 +62,7 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) { // let doc5 = Documents.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { // x: 650, y: 500, width: 600, height: 600, title: "cat 2" // }); - let docset2 = [doc4, doc1, doc3]; + let docset2 = [doc3, doc1, doc2]; let doc6 = Documents.CollectionDocument(docset2, { x: 350, y: 100, width: 600, height: 600, title: "docking collection" }); @@ -76,7 +76,7 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) { mainNodes.Data.push(doc3); // mainNodes.Data.push(doc5); // mainNodes.Data.push(doc1); - //mainNodes.Data.push(doc2); + // mainNodes.Data.push(doc2); mainNodes.Data.push(doc6); mainContainer.Set(KeyStore.Data, mainNodes); } diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index e3d50eb80..d3e90d11c 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -2,7 +2,7 @@ import FlexLayout from "flexlayout-react"; import * as GoldenLayout from "golden-layout"; import 'golden-layout/src/css/goldenlayout-base.css'; import 'golden-layout/src/css/goldenlayout-dark-theme.css'; -import { action, computed } from "mobx"; +import { action, computed, reaction, observable } from "mobx"; import { observer } from "mobx-react"; import * as ReactDOM from 'react-dom'; import { Document } from "../../../fields/Document"; @@ -44,7 +44,7 @@ export class CollectionDockingView extends CollectionViewBase { const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; const value: Document[] = Document.GetData(fieldKey, ListField, []); var docs = value.map(doc => { - return { type: 'component', componentName: 'documentViewComponent', componentState: { doc: doc } }; + return { type: 'component', componentName: 'documentViewComponent', componentState: { doc: doc, scaling: 1 } }; }); return new GoldenLayout({ settings: { @@ -111,6 +111,7 @@ export class CollectionDockingView extends CollectionViewBase { public static myLayout: any = null; + public rcs: Array = new Array(); private static _dragDiv: any = null; private static _dragParent: HTMLElement | null = null; private static _dragElement: HTMLDivElement; @@ -119,7 +120,7 @@ export class CollectionDockingView extends CollectionViewBase { var newItemConfig = { type: 'component', componentName: 'documentViewComponent', - componentState: { doc: dragDoc } + componentState: { doc: dragDoc, scaling: 1 } }; this._dragElement = dragElement; this._dragParent = dragElement.parentElement; @@ -160,7 +161,6 @@ export class CollectionDockingView extends CollectionViewBase { CollectionDockingView.myLayout._maximizedStack = null; } } - // // Creates a vertical split on the right side of the docking view, and then adds the Document to that split // @@ -241,21 +241,8 @@ export class CollectionDockingView extends CollectionViewBase { var containingDiv = "component_" + me.nextId(); container.getElement().html("
"); setTimeout(function () { - var htmlElement = document.getElementById(containingDiv); - container.on('resize', (e: any) => { - // state.doc.SetNumber(KeyStore.Width, htmlElement!.clientWidth); - // if (htmlElement!.clientHeight > 0) - // state.doc.SetNumber(KeyStore.Height, htmlElement!.clientHeight); - }) - ReactDOM.render(( - Transform.Identity} - Scaling={1} - ContainingCollectionView={me} DocumentView={undefined} /> - ), - htmlElement - ); + state.rc = new RenderClass(containingDiv, state.doc, me, container); + me.rcs.push(state.rc); if (CollectionDockingView.myLayout._maxstack != null) { CollectionDockingView.myLayout._maxstack.click(); } @@ -294,4 +281,42 @@ export class CollectionDockingView extends CollectionViewBase {
); } +} + +class RenderClass { + + @observable _resizeCount: number = 0; + + _collectionDockingView: CollectionDockingView; + _htmlElement: any; + _document: Document; + constructor(containingDiv: string, doc: Document, me: CollectionDockingView, container: any) { + this._collectionDockingView = me; + this._htmlElement = document.getElementById(containingDiv); + this._document = doc; + container.on('resize', action((e: any) => { + var nativeWidth = doc.GetNumber(KeyStore.NativeWidth, 0); + if (this._htmlElement != null && this._htmlElement.childElementCount > 0 && nativeWidth > 0) { + let scaling = nativeWidth > 0 ? this._htmlElement!.clientWidth / nativeWidth : 1; + (this._htmlElement!.children[0] as any).style.transformOrigin = "0px 0px"; + (this._htmlElement!.children[0] as any).style.transform = `translate(0px,0px) scale(${scaling}, ${scaling}) `; + (this._htmlElement!.children[0] as any).style.width = nativeWidth.toString() + "px"; + } + })); + + this.render(); + } + render() { + var nativeWidth = this._document.GetNumber(KeyStore.NativeWidth, 0); + let scaling = nativeWidth > 0 ? this._htmlElement!.clientWidth / nativeWidth : 1; + ReactDOM.render(( + Transform.Identity} + Scaling={scaling} + ContainingCollectionView={this._collectionDockingView} DocumentView={undefined} /> + ), + this._htmlElement + ); + } } \ No newline at end of file diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 977a03f58..15450d737 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -17,7 +17,7 @@ import { Transform } from "../../util/Transform"; @observer export class CollectionFreeFormView extends CollectionViewBase { - public static LayoutString() { return CollectionViewBase.LayoutString("CollectionFreeFormView"); } + public static LayoutString(fieldKey: string = "DataKey") { return CollectionViewBase.LayoutString("CollectionFreeFormView", fieldKey); } private _containerRef = React.createRef(); private _canvasRef = React.createRef(); private _lastX: number = 0; @@ -218,6 +218,7 @@ export class CollectionFreeFormView extends CollectionViewBase { const value: Document[] = Document.GetList(this.props.CollectionFieldKey, []); const panx: number = Document.GetNumber(KeyStore.PanX, 0); const pany: number = Document.GetNumber(KeyStore.PanY, 0); + var me = this; return (
{this.props.BackgroundView} @@ -240,7 +241,7 @@ export class CollectionFreeFormView extends CollectionViewBase { AddDocument={this.addDocument} RemoveDocument={this.removeDocument} GetTransform={this.getTransform} - Scaling={this.resizeScaling} + Scaling={1} ContainingCollectionView={this} DocumentView={undefined} />); })}
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 331c4f6fe..f1e882e20 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -27,7 +27,7 @@ export class CollectionSchemaView extends CollectionViewBase { let props: FieldViewProps = { doc: rowProps.value[0], fieldKey: rowProps.value[1], - DocumentViewForField: undefined + DocumentViewForField: undefined, } let contents = ( diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx index eea7908ce..7e2fcb39d 100644 --- a/src/client/views/collections/CollectionViewBase.tsx +++ b/src/client/views/collections/CollectionViewBase.tsx @@ -19,6 +19,7 @@ export interface CollectionViewProps { ContainingDocumentView: Opt; GetTransform: () => Transform; BackgroundView: Opt; + Scaling: number; } export const COLLECTION_BORDER_WIDTH = 2; @@ -26,8 +27,8 @@ export const COLLECTION_BORDER_WIDTH = 2; @observer export class CollectionViewBase extends React.Component { - public static LayoutString(collectionType: string) { - return `<${collectionType} DocumentForCollection={Document} CollectionFieldKey={DataKey} ContainingDocumentView={DocumentView}/>`; + public static LayoutString(collectionType: string, fieldKey: string = "DataKey") { + return `<${collectionType} Scaling={Scaling} DocumentForCollection={Document} CollectionFieldKey={${fieldKey}} ContainingDocumentView={DocumentView} BackgroundView={BackgroundView} />`; } @computed public get active(): boolean { diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 54d3a1b56..9cd42a069 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -238,7 +238,7 @@ export class CollectionFreeFormDocumentView extends DocumentView { onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown}> - +
); } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 691ac6311..3a73f2fde 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -115,7 +115,7 @@ export class DocumentView extends React.Component { 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; + Yy = ry - COLLECTION_BORDER_WIDTH + 18 * Ss; } let W = COLLECTION_BORDER_WIDTH; @@ -158,8 +158,13 @@ export class DocumentView extends React.Component { onError={(test: any) => { console.log(test) }} />; bindings["BackgroundView"] = this.backgroundLayout ? annotated : null; + + 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 ( -
+
{ return (
) diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 60be5f94d..2fa70734d 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -85,10 +85,11 @@ export class ImageBox extends React.Component { 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 nativeWidth = this.props.doc.GetNumber(KeyStore.NativeWidth, 1); return (
- Image not found + Image not found {this.lightbox(path)}
) } -- cgit v1.2.3-70-g09d2