From c67608a7eeeb6bdee27a8e7b4a8f6f8561db6004 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Mon, 21 Jan 2019 22:25:52 -0500 Subject: Small fixes and start of drag drop --- src/views/nodes/DocumentView.tsx | 49 ++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 15 deletions(-) (limited to 'src/views/nodes/DocumentView.tsx') diff --git a/src/views/nodes/DocumentView.tsx b/src/views/nodes/DocumentView.tsx index e37172943..cdc20cdfe 100644 --- a/src/views/nodes/DocumentView.tsx +++ b/src/views/nodes/DocumentView.tsx @@ -12,6 +12,8 @@ import { CollectionFreeFormView } from "../freeformcanvas/CollectionFreeFormView import "./NodeView.scss" import { SelectionManager } from "../../util/SelectionManager"; import { DocumentDecorations } from "../../DocumentDecorations"; +import { SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS } from "constants"; +import { DragManager } from "../../util/DragManager"; const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this? interface IProps { @@ -22,8 +24,11 @@ interface IProps { export class DocumentView extends React.Component { private _mainCont = React.createRef(); - get mainCont(): React.RefObject { - return this._mainCont + get screenRect(): ClientRect | DOMRect { + if(this._mainCont.current) { + return this._mainCont.current.getBoundingClientRect(); + } + return new DOMRect(); } @computed @@ -83,13 +88,26 @@ export class DocumentView extends React.Component { } @computed - get selected() : boolean { + get selected(): boolean { return SelectionManager.IsSelected(this) } private _isPointerDown = false; + componentDidMount() { + if(this._mainCont.current) { + DragManager.MakeDraggable(this._mainCont.current, { + buttons: 3, + handlers: { + dragComplete: () => {}, + dragStart: () => {} + } + }) + } + } + onPointerDown = (e: React.PointerEvent): void => { + return; e.stopPropagation(); if (e.button === 2) { this._isPointerDown = true; @@ -97,8 +115,9 @@ export class DocumentView extends React.Component { document.addEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); document.addEventListener("pointerup", this.onPointerUp); + } else { + SelectionManager.SelectDoc(this, e.ctrlKey) } - SelectionManager.SelectDoc(this, e.ctrlKey) } onPointerUp = (e: PointerEvent): void => { @@ -108,8 +127,6 @@ export class DocumentView extends React.Component { this._isPointerDown = false; document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); - console.log(this.x); - console.log(this.y) DocumentDecorations.Instance.opacity = 1 } } @@ -126,8 +143,8 @@ export class DocumentView extends React.Component { } onDragStart = (e: React.DragEvent): void => { - if (this.mainCont.current !== null) { - this.mainCont.current.style.opacity = "0"; + if (this._mainCont.current !== null) { + this._mainCont.current.style.opacity = "0"; // e.dataTransfer.setDragImage() } } @@ -136,7 +153,7 @@ export class DocumentView extends React.Component { let doc = this.props.dvm.Doc; let bindings: any = { doc: doc, - isSelected: this.selected + isSelected: () => this.selected }; for (const key of this.layoutKeys) { bindings[key.Name + "Key"] = key; @@ -147,22 +164,24 @@ export class DocumentView extends React.Component { bindings[key.Name] = field.GetValue(); } } - + return (
{ e.preventDefault() - }} + }} onPointerDown={this.onPointerDown}> { console.log(test) }} />
); -- cgit v1.2.3-70-g09d2 From 8a1915a73d1d1173059a212db3b79f8efcdd9e9e Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Tue, 22 Jan 2019 20:31:32 -0500 Subject: Temporarily got rid of dvm to draastically improve performance and reduce number of re-renders --- src/Main.tsx | 4 - src/documents/Documents.ts | 2 +- .../freeformcanvas/CollectionFreeFormView.tsx | 3 +- src/views/freeformcanvas/FreeFormCanvas.tsx | 2 +- src/views/nodes/DocumentView.tsx | 130 ++++++++++++--------- test/test.ts | 4 + 6 files changed, 79 insertions(+), 66 deletions(-) (limited to 'src/views/nodes/DocumentView.tsx') diff --git a/src/Main.tsx b/src/Main.tsx index 7c132f179..5482314ae 100644 --- a/src/Main.tsx +++ b/src/Main.tsx @@ -23,12 +23,8 @@ ReactDOM.render((
-
), document.getElementById('root')); -function minus() { - -} runInAction(() => { let doc1 = Documents.TextDocument("Hello world"); let doc2 = doc1.MakeDelegate(); diff --git a/src/documents/Documents.ts b/src/documents/Documents.ts index 084666b95..a2d2218af 100644 --- a/src/documents/Documents.ts +++ b/src/documents/Documents.ts @@ -56,7 +56,7 @@ export namespace Documents { imageProto.SetField(KeyStore.Y, new NumberField(0)); imageProto.SetField(KeyStore.Width, new NumberField(300)); imageProto.SetField(KeyStore.Height, new NumberField(300)); - imageProto.SetField(KeyStore.Layout, new TextField('Image not found')); + imageProto.SetField(KeyStore.Layout, new TextField('Image not found')); // imageProto.SetField(KeyStore.Layout, new TextField('
')); imageProto.SetField(KeyStore.LayoutFields, new ListField([KeyStore.Data])); } diff --git a/src/views/freeformcanvas/CollectionFreeFormView.tsx b/src/views/freeformcanvas/CollectionFreeFormView.tsx index d9a88fcd3..e1aeff534 100644 --- a/src/views/freeformcanvas/CollectionFreeFormView.tsx +++ b/src/views/freeformcanvas/CollectionFreeFormView.tsx @@ -54,7 +54,6 @@ export class CollectionFreeFormView extends React.Component { @action onPointerMove = (e: PointerEvent): void => { - e.preventDefault(); e.stopPropagation(); if (!this._isPointerDown) { return; @@ -97,7 +96,7 @@ export class CollectionFreeFormView extends React.Component {
{value.map(doc => { - return (); + return (); })}
diff --git a/src/views/freeformcanvas/FreeFormCanvas.tsx b/src/views/freeformcanvas/FreeFormCanvas.tsx index de5e88fa1..e051fd97c 100644 --- a/src/views/freeformcanvas/FreeFormCanvas.tsx +++ b/src/views/freeformcanvas/FreeFormCanvas.tsx @@ -80,7 +80,7 @@ export class FreeFormCanvas extends React.Component {
{this.props.store.Docs.map(doc => { - return (); + return (); })}
diff --git a/src/views/nodes/DocumentView.tsx b/src/views/nodes/DocumentView.tsx index cdc20cdfe..648ea7f50 100644 --- a/src/views/nodes/DocumentView.tsx +++ b/src/views/nodes/DocumentView.tsx @@ -14,10 +14,56 @@ import { SelectionManager } from "../../util/SelectionManager"; import { DocumentDecorations } from "../../DocumentDecorations"; import { SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS } from "constants"; import { DragManager } from "../../util/DragManager"; +import { Document } from "../../fields/Document"; const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this? interface IProps { - dvm: DocumentViewModel; + dvm: Document; +} + +@observer +class DocumentContents extends React.Component boolean}> { + + @computed + get layout(): string { + return this.props.dvm.GetFieldValue(KeyStore.Layout, TextField, String("

Error loading layout data

")); + } + + @computed + get layoutKeys(): Key[] { + return this.props.dvm.GetFieldValue(KeyStore.LayoutKeys, ListField, new Array()); + } + + @computed + get layoutFields(): Key[] { + return this.props.dvm.GetFieldValue(KeyStore.LayoutFields, ListField, new Array()); + } + render() { + let doc = this.props.dvm; + let bindings: any = { + doc: doc, + isSelected: this.props.isSelected + }; + for (const key of this.layoutKeys) { + bindings[key.Name + "Key"] = key; + } + for (const key of this.layoutFields) { + let field = doc.GetField(key); + if (field) { + bindings[key.Name] = field.GetValue(); + } + } + return { console.log(test) }} + /> + + + } + } @observer @@ -25,7 +71,7 @@ export class DocumentView extends React.Component { private _mainCont = React.createRef(); get screenRect(): ClientRect | DOMRect { - if(this._mainCont.current) { + if (this._mainCont.current) { return this._mainCont.current.getBoundingClientRect(); } return new DOMRect(); @@ -33,20 +79,20 @@ export class DocumentView extends React.Component { @computed get x(): number { - return this.props.dvm.Doc.GetFieldValue(KeyStore.X, NumberField, Number(0)); + return this.props.dvm.GetFieldValue(KeyStore.X, NumberField, Number(0)); } @computed get y(): number { - return this.props.dvm.Doc.GetFieldValue(KeyStore.Y, NumberField, Number(0)); + return this.props.dvm.GetFieldValue(KeyStore.Y, NumberField, Number(0)); } set x(x: number) { - this.props.dvm.Doc.SetFieldValue(KeyStore.X, x, NumberField) + this.props.dvm.SetFieldValue(KeyStore.X, x, NumberField) } set y(y: number) { - this.props.dvm.Doc.SetFieldValue(KeyStore.Y, y, NumberField) + this.props.dvm.SetFieldValue(KeyStore.Y, y, NumberField) } @computed @@ -56,35 +102,20 @@ export class DocumentView extends React.Component { @computed get width(): number { - return this.props.dvm.Doc.GetFieldValue(KeyStore.Width, NumberField, Number(0)); + return this.props.dvm.GetFieldValue(KeyStore.Width, NumberField, Number(0)); } set width(w: number) { - this.props.dvm.Doc.SetFieldValue(KeyStore.Width, w, NumberField) + this.props.dvm.SetFieldValue(KeyStore.Width, w, NumberField) } @computed get height(): number { - return this.props.dvm.Doc.GetFieldValue(KeyStore.Height, NumberField, Number(0)); + return this.props.dvm.GetFieldValue(KeyStore.Height, NumberField, Number(0)); } set height(h: number) { - this.props.dvm.Doc.SetFieldValue(KeyStore.Height, h, NumberField) - } - - @computed - get layout(): string { - return this.props.dvm.Doc.GetFieldValue(KeyStore.Layout, TextField, String("

Error loading layout data

")); - } - - @computed - get layoutKeys(): Key[] { - return this.props.dvm.Doc.GetFieldValue(KeyStore.LayoutKeys, ListField, new Array()); - } - - @computed - get layoutFields(): Key[] { - return this.props.dvm.Doc.GetFieldValue(KeyStore.LayoutFields, ListField, new Array()); + this.props.dvm.SetFieldValue(KeyStore.Height, h, NumberField) } @computed @@ -92,22 +123,26 @@ export class DocumentView extends React.Component { return SelectionManager.IsSelected(this) } + isSelected = (): boolean => { + return this.selected + } + private _isPointerDown = false; componentDidMount() { - if(this._mainCont.current) { - DragManager.MakeDraggable(this._mainCont.current, { - buttons: 3, - handlers: { - dragComplete: () => {}, - dragStart: () => {} - } - }) - } + return; + // if(this._mainCont.current) { + // DragManager.MakeDraggable(this._mainCont.current, { + // buttons: 2, + // handlers: { + // dragComplete: () => {}, + // dragStart: () => {} + // } + // }) + // } } onPointerDown = (e: React.PointerEvent): void => { - return; e.stopPropagation(); if (e.button === 2) { this._isPointerDown = true; @@ -139,7 +174,7 @@ export class DocumentView extends React.Component { } this.x += e.movementX; this.y += e.movementY; - DocumentDecorations.Instance.opacity = 0 + //DocumentDecorations.Instance.opacity = 0 } onDragStart = (e: React.DragEvent): void => { @@ -150,21 +185,6 @@ export class DocumentView extends React.Component { } render() { - let doc = this.props.dvm.Doc; - let bindings: any = { - doc: doc, - isSelected: () => this.selected - }; - for (const key of this.layoutKeys) { - bindings[key.Name + "Key"] = key; - } - for (const key of this.layoutFields) { - let field = doc.GetField(key); - if (field) { - bindings[key.Name] = field.GetValue(); - } - } - return (
{ e.preventDefault() }} onPointerDown={this.onPointerDown}> - { console.log(test) }} - /> +
); } diff --git a/test/test.ts b/test/test.ts index 8c1740ba6..3c8fae8d7 100644 --- a/test/test.ts +++ b/test/test.ts @@ -40,10 +40,14 @@ describe("Document", () =>{ it('should update', () => { let doc = new Document(); let key = new Key("Test"); + let key2 = new Key("Test2"); let ran = false; reaction(() => doc.GetField(key), (field) => {ran = true}); expect(ran).to.equal(false); + doc.SetField(key2, new NumberField(4)); + expect(ran).to.equal(false); + doc.SetField(key, new NumberField(5)); expect(ran).to.equal(true); -- cgit v1.2.3-70-g09d2 From 122076af3edfd432e6abe3b2571f21034d5c16e5 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Wed, 23 Jan 2019 01:21:15 -0500 Subject: Small changes and more work on drag drop stuff --- src/stores/NodeCollectionStore.ts | 3 +- src/util/DragManager.ts | 62 +++++++++++++++++++++++++---- src/views/freeformcanvas/FreeFormCanvas.tsx | 2 +- src/views/nodes/DocumentView.tsx | 2 +- 4 files changed, 58 insertions(+), 11 deletions(-) (limited to 'src/views/nodes/DocumentView.tsx') diff --git a/src/stores/NodeCollectionStore.ts b/src/stores/NodeCollectionStore.ts index ac4f515f1..7fac83d51 100644 --- a/src/stores/NodeCollectionStore.ts +++ b/src/stores/NodeCollectionStore.ts @@ -15,7 +15,8 @@ export class NodeCollectionStore extends NodeStore { @computed public get Transform(): string { - return "translate(" + this.X + "px," + this.Y + "px) scale(" + this.Scale + "," + this.Scale + ")"; + const halfWidth = window.innerWidth / 2, halfHeight = window.innerHeight / 2; + return `translate(${this.X + halfWidth}px, ${this.Y + halfHeight}px) scale(${this.Scale}) translate(${-halfWidth}px, ${-halfHeight}px)`; } @action diff --git a/src/util/DragManager.ts b/src/util/DragManager.ts index 1da590072..3111d589f 100644 --- a/src/util/DragManager.ts +++ b/src/util/DragManager.ts @@ -14,7 +14,7 @@ export namespace DragManager { buttons: number; } - export interface DragDisposer { + export interface DragDropDisposer { (): void; } @@ -34,7 +34,19 @@ export namespace DragManager { dragComplete: (e: DragCompleteEvent) => void; } - export function MakeDraggable(element: HTMLElement, options: DragOptions): DragDisposer { + export interface DropOptions { + handlers: DropHandlers; + } + + export class DropEvent { + constructor(readonly x: number, readonly y: number) { } + } + + export interface DropHandlers { + drop: (e: DropEvent) => void; + } + + export function MakeDraggable(element: HTMLElement, options: DragOptions): DragDropDisposer { if ("draggable" in element.dataset) { throw new Error("Element is already draggable, can't make it draggable again"); } @@ -53,6 +65,7 @@ export namespace DragManager { dispose(); }; const downHandler = (e: PointerEvent) => { + e.stopPropagation(); document.addEventListener("pointermove", startDragHandler); document.addEventListener("pointerup", upHandler); }; @@ -60,10 +73,26 @@ export namespace DragManager { return () => { element.removeEventListener("pointerdown", downHandler); - element.dataset["draggable"] = undefined; + delete element.dataset["draggable"]; } } + export function MakeDropTarget(element: HTMLElement, options: DropOptions): DragDropDisposer { + if ("draggable" in element.dataset) { + throw new Error("Element is already droppable, can't make it droppable again"); + } + element.dataset["canDrop"] = "true"; + const handler = (e: Event) => { + const ce = e as CustomEvent; + options.handlers.drop(ce.detail); + }; + element.addEventListener("dashOnDrop", handler); + return () => { + element.removeEventListener("dashOnDrop", handler); + delete element.dataset["canDrop"] + }; + } + function StartDrag(ele: HTMLElement, e: PointerEvent, options: DragOptions) { if (!dragDiv) { const root = document.getElementById(rootId); @@ -81,10 +110,16 @@ export namespace DragManager { if (event.cancelled) { return; } - let x = e.x, y = e.y; + const w = ele.offsetWidth, h = ele.offsetHeight; + const rect = ele.getBoundingClientRect(); + const scaleX = rect.width / w, scaleY = rect.height / h; + let x = rect.left, y = rect.top; + // const offsetX = e.x - rect.left, offsetY = e.y - rect.top; let dragElement = ele.cloneNode(true) as HTMLElement; + dragElement.style.opacity = "0.7"; dragElement.style.position = "absolute"; - dragElement.style.transform = `translate(${x}px, ${y}px)`; + dragElement.style.transformOrigin = "0 0"; + dragElement.style.transform = `translate(${x}px, ${y}px) scale(${scaleX}, ${scaleY})`; dragDiv.appendChild(dragElement); const moveHandler = (e: PointerEvent) => { @@ -92,18 +127,29 @@ export namespace DragManager { e.preventDefault(); x += e.movementX; y += e.movementY; - dragElement.style.transform = `translate(${x}px, ${y}px)`; + dragElement.style.transform = `translate(${x}px, ${y}px) scale(${scaleX}, ${scaleY})`; }; const upHandler = (e: PointerEvent) => { document.removeEventListener("pointermove", moveHandler, true); document.removeEventListener("pointerup", upHandler); - FinishDrag(dragElement, options); + FinishDrag(dragElement, e, options); }; document.addEventListener("pointermove", moveHandler, true); document.addEventListener("pointerup", upHandler); } - function FinishDrag(ele: HTMLElement, options: DragOptions) { + function FinishDrag(ele: HTMLElement, e: PointerEvent, options: DragOptions) { dragDiv.removeChild(ele); + const target = document.elementFromPoint(e.x, e.y); + if (!target) { + return; + } + target.dispatchEvent(new CustomEvent("dashOnDrop", { + bubbles: true, + detail: { + x: e.x, + y: e.y, + } + })); } } \ No newline at end of file diff --git a/src/views/freeformcanvas/FreeFormCanvas.tsx b/src/views/freeformcanvas/FreeFormCanvas.tsx index e051fd97c..13e923736 100644 --- a/src/views/freeformcanvas/FreeFormCanvas.tsx +++ b/src/views/freeformcanvas/FreeFormCanvas.tsx @@ -77,7 +77,7 @@ export class FreeFormCanvas extends React.Component { let store = this.props.store; return (
e.preventDefault()}> -
+
{this.props.store.Docs.map(doc => { return (); diff --git a/src/views/nodes/DocumentView.tsx b/src/views/nodes/DocumentView.tsx index 648ea7f50..772c272bd 100644 --- a/src/views/nodes/DocumentView.tsx +++ b/src/views/nodes/DocumentView.tsx @@ -130,7 +130,6 @@ export class DocumentView extends React.Component { private _isPointerDown = false; componentDidMount() { - return; // if(this._mainCont.current) { // DragManager.MakeDraggable(this._mainCont.current, { // buttons: 2, @@ -143,6 +142,7 @@ export class DocumentView extends React.Component { } onPointerDown = (e: React.PointerEvent): void => { + // return; e.stopPropagation(); if (e.button === 2) { this._isPointerDown = true; -- cgit v1.2.3-70-g09d2