aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/util/DragManager.ts68
-rw-r--r--src/views/freeformcanvas/CollectionFreeFormView.tsx59
-rw-r--r--src/views/nodes/DocumentView.tsx110
3 files changed, 95 insertions, 142 deletions
diff --git a/src/util/DragManager.ts b/src/util/DragManager.ts
index 89cf45199..da4537845 100644
--- a/src/util/DragManager.ts
+++ b/src/util/DragManager.ts
@@ -1,4 +1,7 @@
-import { Opt } from "../fields/Field";
+import {Opt} from "../fields/Field";
+import {DocumentView} from "../views/nodes/DocumentView";
+import {DocumentDecorations} from "../DocumentDecorations";
+import {SelectionManager} from "./SelectionManager";
export namespace DragManager {
export let rootId = "root";
@@ -20,20 +23,10 @@ export namespace DragManager {
(): void;
}
- export class DragStartEvent {
- private _cancelled: boolean = false;
- get cancelled() { return this._cancelled };
-
- cancel() { this._cancelled = true; };
-
- constructor(readonly x: number, readonly y: number, readonly data: { [id: string]: any }) { }
- }
-
export class DragCompleteEvent {
}
export interface DragHandlers {
- dragStart: (e: DragStartEvent) => void;
dragComplete: (e: DragCompleteEvent) => void;
}
@@ -42,48 +35,18 @@ export namespace DragManager {
}
export class DropEvent {
- constructor(readonly x: number, readonly y: number, readonly data: { [id: string]: any }) { }
+ constructor(readonly x: number, readonly y: number, readonly data: {[ id: string ]: any}) {}
}
export interface DropHandlers {
drop: (e: Event, de: 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");
- }
- element.dataset["draggable"] = "true";
- const dispose = () => {
- document.removeEventListener("pointerup", upHandler);
- document.removeEventListener("pointermove", startDragHandler);
- }
- const startDragHandler = (e: PointerEvent) => {
- e.stopImmediatePropagation();
- e.preventDefault();
- dispose();
- StartDrag(element, e, options);
- }
- const upHandler = (e: PointerEvent) => {
- dispose();
- };
- const downHandler = (e: PointerEvent) => {
- document.addEventListener("pointermove", startDragHandler);
- document.addEventListener("pointerup", upHandler);
- };
- element.addEventListener("pointerdown", downHandler);
-
- return () => {
- element.removeEventListener("pointerdown", downHandler);
- delete element.dataset["draggable"];
- }
- }
-
export function MakeDropTarget(element: HTMLElement, options: DropOptions): DragDropDisposer {
- if ("draggable" in element.dataset) {
+ if ("canDrop" in element.dataset) {
throw new Error("Element is already droppable, can't make it droppable again");
}
- element.dataset["canDrop"] = "true";
+ element.dataset[ "canDrop" ] = "true";
const handler = (e: Event) => {
const ce = e as CustomEvent<DropEvent>;
options.handlers.drop(e, ce.detail);
@@ -91,11 +54,11 @@ export namespace DragManager {
element.addEventListener("dashOnDrop", handler);
return () => {
element.removeEventListener("dashOnDrop", handler);
- delete element.dataset["canDrop"]
+ delete element.dataset[ "canDrop" ]
};
}
- function StartDrag(ele: HTMLElement, e: PointerEvent, options: DragOptions) {
+ export function StartDrag(ele: HTMLElement, dragData: {[ id: string ]: any}, options: DragOptions) {
if (!dragDiv) {
const root = document.getElementById(rootId);
if (!root) {
@@ -104,17 +67,6 @@ export namespace DragManager {
dragDiv = document.createElement("div");
root.appendChild(dragDiv);
}
- if ((e.buttons & options.buttons) === 0) {
- return;
- }
- e.stopPropagation();
- e.preventDefault();
- let dragData = {};
- let event = new DragStartEvent(e.x, e.y, dragData);
- options.handlers.dragStart(event);
- if (event.cancelled) {
- return;
- }
const w = ele.offsetWidth, h = ele.offsetHeight;
const rect = ele.getBoundingClientRect();
const scaleX = rect.width / w, scaleY = rect.height / h;
@@ -157,7 +109,7 @@ export namespace DragManager {
document.addEventListener("pointerup", upHandler);
}
- function FinishDrag(dragEle: HTMLElement, e: PointerEvent, options: DragOptions, dragData: { [index: string]: any }) {
+ function FinishDrag(dragEle: HTMLElement, e: PointerEvent, options: DragOptions, dragData: {[ index: string ]: any}) {
dragDiv.removeChild(dragEle);
const target = document.elementFromPoint(e.x, e.y);
if (!target) {
diff --git a/src/views/freeformcanvas/CollectionFreeFormView.tsx b/src/views/freeformcanvas/CollectionFreeFormView.tsx
index f3ee2da23..fc473f0a6 100644
--- a/src/views/freeformcanvas/CollectionFreeFormView.tsx
+++ b/src/views/freeformcanvas/CollectionFreeFormView.tsx
@@ -1,20 +1,20 @@
-import { observer } from "mobx-react";
-import { Key, KeyStore } from "../../fields/Key";
+import {observer} from "mobx-react";
+import {Key, KeyStore} from "../../fields/Key";
import React = require("react");
-import { action, observable, computed } from "mobx";
-import { Document } from "../../fields/Document";
-import { DocumentViewModel } from "../../viewmodels/DocumentViewModel";
-import { DocumentView } from "../nodes/DocumentView";
-import { ListField } from "../../fields/ListField";
-import { NumberField } from "../../fields/NumberField";
-import { SSL_OP_SINGLE_DH_USE } from "constants";
-import { DocumentDecorations } from "../../DocumentDecorations";
-import { SelectionManager } from "../../util/SelectionManager";
-import { Documents } from "../../documents/Documents";
-import { ContextMenu } from "../ContextMenu";
-import { Opt } from "../../fields/Field";
-import { DragManager } from "../../util/DragManager";
-import { Utils } from "../../Utils";
+import {action, observable, computed} from "mobx";
+import {Document} from "../../fields/Document";
+import {DocumentViewModel} from "../../viewmodels/DocumentViewModel";
+import {DocumentView} from "../nodes/DocumentView";
+import {ListField} from "../../fields/ListField";
+import {NumberField} from "../../fields/NumberField";
+import {SSL_OP_SINGLE_DH_USE} from "constants";
+import {DocumentDecorations} from "../../DocumentDecorations";
+import {SelectionManager} from "../../util/SelectionManager";
+import {Documents} from "../../documents/Documents";
+import {ContextMenu} from "../ContextMenu";
+import {Opt} from "../../fields/Field";
+import {DragManager} from "../../util/DragManager";
+import {Utils} from "../../Utils";
interface IProps {
fieldKey: Key;
@@ -44,15 +44,15 @@ export class CollectionFreeFormView extends React.Component<IProps> {
if (!ele) {
return;
}
- const doc = de.data["document"];
- const xOffset = de.data["xOffset"] as number || 0;
- const yOffset = de.data["yOffset"] as number || 0;
+ const doc = de.data[ "document" ];
+ const xOffset = de.data[ "xOffset" ] as number || 0;
+ const yOffset = de.data[ "yOffset" ] as number || 0;
if (doc instanceof DocumentView) {
if (doc.props.ContainingCollectionView && doc.props.ContainingCollectionView !== this) {
doc.props.ContainingCollectionView.removeDocument(doc.props.Document);
this.addDocument(doc.props.Document);
}
- const { scale, translateX, translateY } = Utils.GetScreenTransform(ele);
+ const {scale, translateX, translateY} = Utils.GetScreenTransform(ele);
const screenX = de.x - xOffset;
const screenY = de.y - yOffset;
const docX = (screenX - translateX) / scale;
@@ -61,7 +61,7 @@ export class CollectionFreeFormView extends React.Component<IProps> {
doc.y = docY;
}
e.stopPropagation();
-
+ DocumentDecorations.Instance.forceUpdate();
}
componentDidMount() {
@@ -95,11 +95,6 @@ export class CollectionFreeFormView extends React.Component<IProps> {
document.removeEventListener("pointermove", this.onPointerMove);
document.removeEventListener("pointerup", this.onPointerUp);
e.stopPropagation();
-
- var topMost = this.props.ContainingDocumentView != undefined && this.props.ContainingDocumentView.props.ContainingCollectionView == undefined;
- if (topMost) {
- SelectionManager.DeselectAll()
- }
}
@action
@@ -131,7 +126,7 @@ export class CollectionFreeFormView extends React.Component<IProps> {
let ContainerY = inputY;
if (me.props.ContainingDocumentView != undefined) {
let pme = me.props.ContainingDocumentView!;
- let { LocalX, LocalY } = this.getLocalPoint(pme, ContainerX, ContainerY);
+ let {LocalX, LocalY} = this.getLocalPoint(pme, ContainerX, ContainerY);
ContainerX = LocalX;
ContainerY = LocalY;
}
@@ -145,14 +140,14 @@ export class CollectionFreeFormView extends React.Component<IProps> {
let LocalX = W / 2 - (Xx + Panxx) / Ss + (ContainerX - W / 2) / Ss;
let LocalY = -(Yy + Panyy) / Ss + ContainerY / Ss;
- return { LocalX, Ss, W, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY };
+ return {LocalX, Ss, W, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY};
}
@action
onPointerWheel = (e: React.WheelEvent): void => {
e.stopPropagation();
- let { LocalX, Ss, W, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY } = this.getLocalPoint(this.props.ContainingDocumentView!, e.pageX, e.pageY);
+ let {LocalX, Ss, W, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY} = this.getLocalPoint(this.props.ContainingDocumentView!, e.pageX, e.pageY);
var deltaScale = (1 - (e.deltaY / 1000)) * Ss;
@@ -173,7 +168,7 @@ export class CollectionFreeFormView extends React.Component<IProps> {
e.stopPropagation()
e.preventDefault()
let fReader = new FileReader()
- let file = e.dataTransfer.items[0].getAsFile();
+ let file = e.dataTransfer.items[ 0 ].getAsFile();
let that = this;
const panx: number = this.props.Document.GetFieldValue(KeyStore.PanX, NumberField, Number(0));
const pany: number = this.props.Document.GetFieldValue(KeyStore.PanY, NumberField, Number(0));
@@ -222,7 +217,7 @@ export class CollectionFreeFormView extends React.Component<IProps> {
onDragOver = (e: React.DragEvent): void => {
}
render() {
- const { fieldKey, Document: Document } = this.props;
+ const {fieldKey, Document: Document} = this.props;
const value: Document[] = Document.GetFieldValue(fieldKey, ListField, []);
const panx: number = Document.GetFieldValue(KeyStore.PanX, NumberField, Number(0));
@@ -239,7 +234,7 @@ export class CollectionFreeFormView extends React.Component<IProps> {
height: "calc(100% - 4px)",
overflow: "hidden"
}} onDrop={this.onDrop} onDragOver={this.onDragOver} ref={this._containerRef}>
- <div className="collectionfreeformview" style={{ transform: `translate(${panx}px, ${pany}px) scale(${currScale}, ${currScale})`, transformOrigin: `left, top` }} ref={this._canvasRef}>
+ <div className="collectionfreeformview" style={{transform: `translate(${panx}px, ${pany}px) scale(${currScale}, ${currScale})`, transformOrigin: `left, top`}} ref={this._canvasRef}>
<div className="node-container">
{value.map(doc => {
diff --git a/src/views/nodes/DocumentView.tsx b/src/views/nodes/DocumentView.tsx
index 602d28d56..da2768bbe 100644
--- a/src/views/nodes/DocumentView.tsx
+++ b/src/views/nodes/DocumentView.tsx
@@ -1,20 +1,20 @@
-import { observer } from "mobx-react";
+import {observer} from "mobx-react";
import React = require("react");
-import { computed, observable, action } from "mobx";
-import { KeyStore, Key } from "../../fields/Key";
-import { NumberField } from "../../fields/NumberField";
-import { TextField } from "../../fields/TextField";
-import { DocumentViewModel } from "../../viewmodels/DocumentViewModel";
-import { ListField } from "../../fields/ListField";
-import { FieldTextBox } from "../nodes/FieldTextBox"
-import { Document } from "../../fields/Document";
-import { CollectionFreeFormView } from "../freeformcanvas/CollectionFreeFormView"
+import {computed, observable, action} from "mobx";
+import {KeyStore, Key} from "../../fields/Key";
+import {NumberField} from "../../fields/NumberField";
+import {TextField} from "../../fields/TextField";
+import {DocumentViewModel} from "../../viewmodels/DocumentViewModel";
+import {ListField} from "../../fields/ListField";
+import {FieldTextBox} from "../nodes/FieldTextBox"
+import {Document} from "../../fields/Document";
+import {CollectionFreeFormView} from "../freeformcanvas/CollectionFreeFormView"
import "./NodeView.scss"
-import { SelectionManager } from "../../util/SelectionManager";
-import { DocumentDecorations } from "../../DocumentDecorations";
-import { ContextMenu } from "../ContextMenu";
-import { Opt } from "../../fields/Field";
-import { DragManager } from "../../util/DragManager";
+import {SelectionManager} from "../../util/SelectionManager";
+import {DocumentDecorations} from "../../DocumentDecorations";
+import {ContextMenu} from "../ContextMenu";
+import {Opt} from "../../fields/Field";
+import {DragManager} from "../../util/DragManager";
const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this?
interface IProps {
@@ -42,22 +42,22 @@ class DocumentContents extends React.Component<IProps> {
}
render() {
let doc = this.props.Document;
- let bindings = { ...this.props } as any;
+ let bindings = {...this.props} as any;
for (const key of this.layoutKeys) {
- bindings[key.Name + "Key"] = key;
+ bindings[ key.Name + "Key" ] = key;
}
for (const key of this.layoutFields) {
let field = doc.GetField(key);
if (field) {
- bindings[key.Name] = field.GetValue();
+ bindings[ key.Name ] = field.GetValue();
}
}
return <JsxParser
- components={{ FieldTextBox, CollectionFreeFormView }}
+ components={{FieldTextBox, CollectionFreeFormView}}
bindings={bindings}
jsx={this.layout}
showWarnings={true}
- onError={(test: any) => { console.log(test) }}
+ onError={(test: any) => {console.log(test)}}
/>
@@ -117,56 +117,59 @@ export class DocumentView extends React.Component<IProps> {
set height(h: number) {
this.props.Document.SetFieldValue(KeyStore.Height, h, NumberField)
}
-
- @action
- dragStarted = (e: DragManager.DragStartEvent) => {
- this._contextMenuCanOpen = false;
- if (!this.props.ContainingCollectionView) {
- e.cancel();
- return;
- }
- const rect = this.screenRect;
- e.data["document"] = this;
- e.data["xOffset"] = e.x - rect.left;
- e.data["yOffset"] = e.y - rect.top;
- }
-
@action
dragComplete = (e: DragManager.DragCompleteEvent) => {
}
- componentDidMount() {
- if (this._mainCont.current) {
- DragManager.MakeDraggable(this._mainCont.current, {
- buttons: 2,
- handlers: {
- dragComplete: this.dragComplete,
- dragStart: this.dragStarted
- },
- hideSource: true
- })
- }
- }
-
@computed
get active(): boolean {
- return SelectionManager.IsSelected(this) || (this.props.ContainingCollectionView !== undefined && this.props.ContainingCollectionView.active);
+ return SelectionManager.IsSelected(this) || this.props.ContainingCollectionView === undefined || this.props.ContainingCollectionView!.active;
}
private _downX: number = 0;
private _downY: number = 0;
onPointerDown = (e: React.PointerEvent): void => {
- e.stopPropagation();
+ let me = this;
this._downX = e.clientX;
this._downY = e.clientY;
this._contextMenuCanOpen = e.button == 2;
- document.addEventListener("pointerup", this.onPointerUp);
+ if (this.active) {
+ e.stopPropagation();
+ e.preventDefault();
+ document.removeEventListener("pointermove", this.onPointerMove)
+ document.addEventListener("pointermove", this.onPointerMove);
+ document.removeEventListener("pointerup", this.onPointerUp)
+ document.addEventListener("pointerup", this.onPointerUp);
+ }
+ }
+
+ onPointerMove = (e: PointerEvent): void => {
+ if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) {
+ if (this._mainCont.current != null && this.props.ContainingCollectionView != null) {
+ this._contextMenuCanOpen = false;
+ const rect = this.screenRect;
+ let dragData: {[ id: string ]: any} = {};
+ dragData[ "document" ] = this;
+ dragData[ "xOffset" ] = e.x - rect.left;
+ dragData[ "yOffset" ] = e.y - rect.top;
+ DragManager.StartDrag(this._mainCont.current, dragData, {
+ buttons: 2,
+ handlers: {
+ dragComplete: this.dragComplete,
+ },
+ hideSource: true
+ })
+ }
+ }
+ e.stopPropagation();
+ e.preventDefault();
}
onPointerUp = (e: PointerEvent): void => {
+ document.removeEventListener("pointermove", this.onPointerMove)
document.removeEventListener("pointerup", this.onPointerUp)
e.stopPropagation();
- if ((e.clientX - this._downX) == 0 && (e.clientY - this._downY) == 0) {
+ if (Math.abs(e.clientX - this._downX) < 4 && Math.abs(e.clientY - this._downY) < 4) {
SelectionManager.SelectDoc(this, e.ctrlKey);
}
}
@@ -179,6 +182,9 @@ export class DocumentView extends React.Component<IProps> {
@action
onContextMenu = (e: React.MouseEvent): void => {
+ if (!SelectionManager.IsSelected(this)) {
+ return;
+ }
e.preventDefault()
if (!this._contextMenuCanOpen) {
@@ -194,7 +200,7 @@ export class DocumentView extends React.Component<IProps> {
e.stopPropagation();
ContextMenu.Instance.clearItems();
- ContextMenu.Instance.addItem({ description: "Delete", event: this.deleteClicked })
+ ContextMenu.Instance.addItem({description: "Delete", event: this.deleteClicked})
ContextMenu.Instance.displayMenu(e.pageX, e.pageY)
SelectionManager.SelectDoc(this, e.ctrlKey);
}