aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanley Yip <stanley_yip@brown.edu>2020-02-11 22:37:53 -0500
committerStanley Yip <stanley_yip@brown.edu>2020-02-11 22:37:53 -0500
commit2829d080ad27dac6bd2a4b717817a5681343556a (patch)
tree2fc931fd5f5cab7e596d484aa846026c4bf679de
parent832dbcba3d46a924cca583429f683672875964a4 (diff)
parent3910d017f6f06ebaf78884e9935d9206505427b8 (diff)
Merge branch 'radial_menu_fixes2' of https://github.com/browngraphicslab/Dash-Web into pen
-rw-r--r--src/client/util/SelectionManager.ts1
-rw-r--r--src/client/views/GestureOverlay.tsx108
-rw-r--r--src/client/views/MainView.tsx2
-rw-r--r--src/client/views/Touchable.tsx4
-rw-r--r--src/client/views/nodes/DocumentView.tsx73
-rw-r--r--src/client/views/nodes/RadialMenu.tsx75
6 files changed, 162 insertions, 101 deletions
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 86a7a620e..4fd8abb12 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -56,6 +56,7 @@ export namespace SelectionManager {
export function SelectDoc(docView: DocumentView, ctrlPressed: boolean): void {
manager.SelectDoc(docView, ctrlPressed);
}
+
export function IsSelected(doc: DocumentView, outsideReaction?: boolean): boolean {
return outsideReaction ?
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 5c4dd0c0a..9a601e07b 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -27,6 +27,9 @@ import { listSpec } from "../../new_fields/Schema";
import { List } from "../../new_fields/List";
import { CollectionViewType } from "./collections/CollectionView";
import TouchScrollableMenu, { TouchScrollableMenuItem } from "./TouchScrollableMenu";
+import { RadialMenu } from "./nodes/RadialMenu";
+import { SelectionManager } from "../util/SelectionManager";
+
@observer
export default class GestureOverlay extends Touchable {
@@ -104,6 +107,15 @@ export default class GestureOverlay extends Touchable {
}
onReactTouchStart = (te: React.TouchEvent) => {
+ document.removeEventListener("touchmove", this.onReactHoldTouchMove);
+ document.removeEventListener("touchend", this.onReactHoldTouchEnd);
+ if (RadialMenu.Instance._display === true) {
+ te.preventDefault();
+ te.stopPropagation();
+ RadialMenu.Instance.closeMenu();
+ return;
+ }
+
const actualPts: React.Touch[] = [];
for (let i = 0; i < te.touches.length; i++) {
const pt: any = te.touches.item(i);
@@ -127,9 +139,10 @@ export default class GestureOverlay extends Touchable {
ptsToDelete.forEach(pt => this.prevPoints.delete(pt));
const nts = this.getNewTouches(te);
-
if (nts.nt.length < 5) {
const target = document.elementFromPoint(te.changedTouches.item(0).clientX, te.changedTouches.item(0).clientY);
+ te.changedTouches.item(0).identifier;
+ console.log(te.touches);
target?.dispatchEvent(
new CustomEvent<InteractionUtils.MultiTouchEvent<React.TouchEvent>>("dashOnTouchStart",
{
@@ -144,34 +157,41 @@ export default class GestureOverlay extends Touchable {
}
)
);
- // if (this.prevPoints.size === 1 && this._holdTimer === undefined) {
- // console.log("started");
- // this._holdTimer = setTimeout(() => {
- // console.log("hold");
- // const target = document.elementFromPoint(te.changedTouches.item(0).clientX, te.changedTouches.item(0).clientY);
- // target?.dispatchEvent(
- // new CustomEvent<InteractionUtils.MultiTouchEvent<React.TouchEvent>>("dashOnTouchHoldStart",
- // {
- // bubbles: true,
- // detail: {
- // fingers: this.prevPoints.size,
- // targetTouches: nts.ntt,
- // touches: nts.nt,
- // changedTouches: nts.nct,
- // touchEvent: te
- // }
- // }
- // )
- // );
- // this._holdTimer = undefined;
- // document.removeEventListener("touchmove", this.onReactTouchMove);
- // document.removeEventListener("touchend", this.onReactTouchEnd);
- // document.removeEventListener("touchmove", this.onReactHoldTouchMove);
- // document.removeEventListener("touchend", this.onReactHoldTouchEnd);
- // document.addEventListener("touchmove", this.onReactHoldTouchMove);
- // document.addEventListener("touchend", this.onReactHoldTouchEnd);
- // }, (1000));
- // }
+ if (nts.nt.length === 1) {
+ console.log("started");
+ this._holdTimer = setTimeout(() => {
+ console.log("hold");
+ const target = document.elementFromPoint(te.changedTouches.item(0).clientX, te.changedTouches.item(0).clientY);
+ let pt: any = te.touches[te.touches.length - 1];
+ if (nts.nt.length === 1 && pt.radiusX > 1 && pt.radiusY > 1) {
+ target?.dispatchEvent(
+ new CustomEvent<InteractionUtils.MultiTouchEvent<React.TouchEvent>>("dashOnTouchHoldStart",
+ {
+ bubbles: true,
+ detail: {
+ fingers: this.prevPoints.size,
+ targetTouches: nts.ntt,
+ touches: nts.nt,
+ changedTouches: nts.nct,
+ touchEvent: te
+ }
+ }
+ )
+ );
+ this._holdTimer = undefined;
+ document.removeEventListener("touchmove", this.onReactTouchMove);
+ document.removeEventListener("touchend", this.onReactTouchEnd);
+ document.removeEventListener("touchmove", this.onReactHoldTouchMove);
+ document.removeEventListener("touchend", this.onReactHoldTouchEnd);
+ document.addEventListener("touchmove", this.onReactHoldTouchMove);
+ document.addEventListener("touchend", this.onReactHoldTouchEnd);
+ }
+
+ }, (500));
+ }
+ else {
+ clearTimeout(this._holdTimer);
+ }
document.removeEventListener("touchmove", this.onReactTouchMove);
document.removeEventListener("touchend", this.onReactTouchEnd);
document.addEventListener("touchmove", this.onReactTouchMove);
@@ -185,10 +205,15 @@ export default class GestureOverlay extends Touchable {
}
onReactHoldTouchMove = (e: TouchEvent) => {
+ document.removeEventListener("touchmove", this.onReactTouchMove);
+ document.removeEventListener("touchend", this.onReactTouchEnd);
+ document.removeEventListener("touchmove", this.onReactHoldTouchMove);
+ document.removeEventListener("touchend", this.onReactHoldTouchEnd);
+ document.addEventListener("touchmove", this.onReactHoldTouchMove);
+ document.addEventListener("touchend", this.onReactHoldTouchEnd);
const nts: any = this.getNewTouches(e);
if (this.prevPoints.size === 1 && this._holdTimer) {
clearTimeout(this._holdTimer);
- this._holdTimer = undefined;
}
document.dispatchEvent(
new CustomEvent<InteractionUtils.MultiTouchEvent<TouchEvent>>("dashOnTouchHoldMove",
@@ -233,20 +258,18 @@ export default class GestureOverlay extends Touchable {
}
}
- if (this.prevPoints.size === 0) {
- document.removeEventListener("touchmove", this.onReactTouchMove);
- document.removeEventListener("touchend", this.onReactTouchEnd);
- }
+ document.removeEventListener("touchmove", this.onReactHoldTouchMove);
+ document.removeEventListener("touchend", this.onReactHoldTouchEnd);
+
e.stopPropagation();
}
onReactTouchMove = (e: TouchEvent) => {
const nts: any = this.getNewTouches(e);
- if (this.prevPoints.size === 1 && this._holdTimer) {
- clearTimeout(this._holdTimer);
- this._holdTimer = undefined;
- }
+ clearTimeout(this._holdTimer);
+ this._holdTimer = undefined;
+
document.dispatchEvent(
new CustomEvent<InteractionUtils.MultiTouchEvent<TouchEvent>>("dashOnTouchMove",
{
@@ -264,10 +287,9 @@ export default class GestureOverlay extends Touchable {
onReactTouchEnd = (e: TouchEvent) => {
const nts: any = this.getNewTouches(e);
- if (this.prevPoints.size === 1 && this._holdTimer) {
- clearTimeout(this._holdTimer);
- this._holdTimer = undefined;
- }
+ clearTimeout(this._holdTimer);
+ this._holdTimer = undefined;
+
document.dispatchEvent(
new CustomEvent<InteractionUtils.MultiTouchEvent<TouchEvent>>("dashOnTouchEnd",
{
@@ -298,6 +320,7 @@ export default class GestureOverlay extends Touchable {
}
handleHandDown = async (e: React.TouchEvent) => {
+ clearTimeout(this._holdTimer!);
const fingers = new Array<React.Touch>();
for (let i = 0; i < e.touches.length; i++) {
const pt: any = e.touches.item(i);
@@ -347,6 +370,7 @@ export default class GestureOverlay extends Touchable {
const thumbDoc = await Cast(CurrentUserUtils.setupThumbDoc(CurrentUserUtils.UserDocument), Doc);
if (thumbDoc) {
runInAction(() => {
+ RadialMenu.Instance._display = false;
this._inkToTextDoc = FieldValue(Cast(thumbDoc.inkToTextDoc, Doc));
this._thumbDoc = thumbDoc;
this._thumbX = thumb.clientX;
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 92b26b9bc..997266266 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -531,7 +531,7 @@ export class MainView extends React.Component {
</GestureOverlay>
<PreviewCursor />
<ContextMenu />
- {/* <RadialMenu /> */}
+ <RadialMenu />
<PDFMenu />
<MarqueeOptionsMenu />
<RichTextMenu />
diff --git a/src/client/views/Touchable.tsx b/src/client/views/Touchable.tsx
index 13cc38589..bc3d07130 100644
--- a/src/client/views/Touchable.tsx
+++ b/src/client/views/Touchable.tsx
@@ -221,8 +221,8 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
handle1PointerHoldMove = (e: Event, me: InteractionUtils.MultiTouchEvent<TouchEvent>): void => {
- e.stopPropagation();
- me.touchEvent.stopPropagation();
+ // e.stopPropagation();
+ // me.touchEvent.stopPropagation();
}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 765077c4d..aa07db2a0 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -124,50 +124,71 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
private _firstY: number = -1;
+
handle1PointerHoldStart = (e: Event, me: InteractionUtils.MultiTouchEvent<React.TouchEvent>): any => {
- this.addHoldMoveListeners();
- this.addHoldEndListeners();
- this.onRadialMenu(e, me);
- const pt = InteractionUtils.GetMyTargetTouches(me, this.prevPoints, true)[0];
- this._firstX = pt.pageX;
- this._firstY = pt.pageY;
+ this.removeMoveListeners();
+ this.removeEndListeners();
+ document.removeEventListener("pointermove", this.onPointerMove);
+ document.removeEventListener("pointerup", this.onPointerUp);
+ console.log(SelectionManager.SelectedDocuments());
+ console.log("START");
+ if (RadialMenu.Instance._display === false) {
+ this.addHoldMoveListeners();
+ this.addHoldEndListeners();
+ this.onRadialMenu(e, me);
+ const pt = me.touchEvent.touches[me.touchEvent.touches.length - 1];
+ this._firstX = pt.pageX;
+ this._firstY = pt.pageY;
+ }
}
handle1PointerHoldMove = (e: Event, me: InteractionUtils.MultiTouchEvent<TouchEvent>): void => {
- const pt = InteractionUtils.GetMyTargetTouches(me, this.prevPoints, true)[0];
- console.log(pt.pageX, this._firstX, pt.pageY, this._firstY);
+
+ const pt = me.touchEvent.touches[me.touchEvent.touches.length - 1];
+
if (this._firstX === -1 || this._firstY === -1) {
return;
}
if (Math.abs(pt.pageX - this._firstX) > 150 || Math.abs(pt.pageY - this._firstY) > 150) {
- console.log("WHY");
this.handle1PointerHoldEnd(e, me);
}
}
handle1PointerHoldEnd = (e: Event, me: InteractionUtils.MultiTouchEvent<TouchEvent>): void => {
+ this.removeHoldMoveListeners();
+ this.removeHoldEndListeners();
RadialMenu.Instance.closeMenu();
this._firstX = -1;
this._firstY = -1;
+ SelectionManager.DeselectAll();
+ me.touchEvent.stopPropagation();
+ me.touchEvent.preventDefault();
+ e.stopPropagation();
+
+
}
@action
onRadialMenu = (e: Event, me: InteractionUtils.MultiTouchEvent<React.TouchEvent>): void => {
- const pt = InteractionUtils.GetMyTargetTouches(me, this.prevPoints, true)[0];
+ console.log("DISPLAYMENUUUU");
+ console.log(me.touchEvent.touches);
+ // console.log(InteractionUtils.GetMyTargetTouches(me, this.prevPoints, true));
+ // const pt = InteractionUtils.GetMyTargetTouches(me, this.prevPoints, true)[0];
+ const pt = me.touchEvent.touches[me.touchEvent.touches.length - 1];
+ RadialMenu.Instance.openMenu(pt.pageX - 15, pt.pageY - 15);
- RadialMenu.Instance.openMenu();
+ RadialMenu.Instance.addItem({ description: "Open Fields", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { width: 300, height: 300 }), undefined, "onRight"), icon: "map-pin", selected: -1 });
+ RadialMenu.Instance.addItem({ description: "Delete this document", event: () => { this.props.ContainingCollectionView?.removeDocument(this.props.Document), RadialMenu.Instance.closeMenu() }, icon: "layer-group", selected: -1 });
+ RadialMenu.Instance.addItem({ description: "Open in a new tab", event: () => this.props.addDocTab(this.props.Document, undefined, "onRight"), icon: "trash", selected: -1 });
+ RadialMenu.Instance.addItem({ description: "Pin to Presentation", event: () => this.props.pinToPres(this.props.Document), icon: "folder", selected: -1 });
+
+ // if (SelectionManager.IsSelected(this, true)) {
+ // SelectionManager.SelectDoc(this, false);
+ // }
+ SelectionManager.DeselectAll();
- RadialMenu.Instance.addItem({ description: "Open Fields", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { width: 300, height: 300 }), undefined, "onRight"), icon: "layer-group", selected: -1 });
- RadialMenu.Instance.addItem({ description: "Delete this document", event: () => this.props.ContainingCollectionView?.removeDocument(this.props.Document), icon: "trash", selected: -1 });
- RadialMenu.Instance.addItem({ description: "Open in a new tab", event: () => this.props.addDocTab(this.props.Document, undefined, "onRight"), icon: "folder", selected: -1 });
- RadialMenu.Instance.addItem({ description: "Pin to Presentation", event: () => this.props.pinToPres(this.props.Document), icon: "map-pin", selected: -1 });
- RadialMenu.Instance.displayMenu(pt.pageX - 15, pt.pageY - 15);
- if (!SelectionManager.IsSelected(this, true)) {
- SelectionManager.SelectDoc(this, false);
- }
- e.stopPropagation();
}
@action
@@ -189,7 +210,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
this._mainCont.current && (this._dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, this.drop.bind(this)));
this._mainCont.current && (this._gestureEventDisposer = GestureUtils.MakeGestureTarget(this._mainCont.current, this.onGesture.bind(this)));
this._mainCont.current && (this.multiTouchDisposer = InteractionUtils.MakeMultiTouchTarget(this._mainCont.current, this.onTouchStart.bind(this)));
- // this._mainCont.current && (this.holdDisposer = InteractionUtils.MakeHoldTouchTarget(this._mainCont.current, this.handle1PointerHoldStart.bind(this)));
+ this._mainCont.current && (this.holdDisposer = InteractionUtils.MakeHoldTouchTarget(this._mainCont.current, this.handle1PointerHoldStart.bind(this)));
}
@action
@@ -315,8 +336,10 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
}
handle1PointerDown = (e: React.TouchEvent, me: InteractionUtils.MultiTouchEvent<React.TouchEvent>) => {
+ SelectionManager.DeselectAll();
if (this.Document.onPointerDown) return;
- const touch = InteractionUtils.GetMyTargetTouches(me, this.prevPoints, true)[0];
+ const touch = me.touchEvent.changedTouches.item(0);
+ console.log("DOWN", SelectionManager.SelectedDocuments());
console.log("down");
if (touch) {
this._downX = touch.clientX;
@@ -344,7 +367,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
this.removeMoveListeners();
}
else if (!e.cancelBubble && (SelectionManager.IsSelected(this, true) || this.props.parentActive(true) || this.Document.onDragStart || this.Document.onClick) && !this.Document.lockedPosition && !this.Document.inOverlay) {
- const touch = InteractionUtils.GetMyTargetTouches(me, this.prevPoints, true)[0];
+
+ const touch = me.touchEvent.changedTouches.item(0);
if (Math.abs(this._downX - touch.clientX) > 3 || Math.abs(this._downY - touch.clientY) > 3) {
if (!e.altKey && (!this.topMost || this.Document.onDragStart || this.Document.onClick)) {
this.cleanUpInteractions();
@@ -498,11 +522,14 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
}
onPointerUp = (e: PointerEvent): void => {
+ this.cleanUpInteractions();
+
if (this.onPointerUpHandler && this.onPointerUpHandler.script && !InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) {
this.onPointerUpHandler.script.run({ this: this.Document.isTemplateForField && this.props.DataDoc ? this.props.DataDoc : this.props.Document }, console.log);
document.removeEventListener("pointerup", this.onPointerUp);
return;
}
+
document.removeEventListener("pointermove", this.onPointerMove);
document.removeEventListener("pointerup", this.onPointerUp);
this._doubleTap = (Date.now() - this._lastTap < 300 && e.button === 0 && Math.abs(e.clientX - this._downX) < 2 && Math.abs(e.clientY - this._downY) < 2);
diff --git a/src/client/views/nodes/RadialMenu.tsx b/src/client/views/nodes/RadialMenu.tsx
index 74c5f53bd..a6fb72a7b 100644
--- a/src/client/views/nodes/RadialMenu.tsx
+++ b/src/client/views/nodes/RadialMenu.tsx
@@ -24,12 +24,19 @@ export class RadialMenu extends React.Component {
private _reactionDisposer?: IReactionDisposer;
+ catchTouch = (te: React.TouchEvent) => {
+ console.log("caught");
+ te.stopPropagation();
+ te.preventDefault();
+ }
+
@action
onPointerDown = (e: PointerEvent) => {
this._mouseDown = true;
this._mouseX = e.clientX;
this._mouseY = e.clientY;
document.addEventListener("pointermove", this.onPointerMove);
+
}
@observable
@@ -42,7 +49,6 @@ export class RadialMenu extends React.Component {
const deltX = this._mouseX - curX;
const deltY = this._mouseY - curY;
const scale = Math.hypot(deltY, deltX);
-
if (scale < 150 && scale > 50) {
const rad = Math.atan2(deltY, deltX) + Math.PI;
let closest = 0;
@@ -83,6 +89,7 @@ export class RadialMenu extends React.Component {
@action
componentDidMount = () => {
+ console.log(this._pageX);
document.addEventListener("pointerdown", this.onPointerDown);
document.addEventListener("pointerup", this.onPointerUp);
this.previewcircle();
@@ -98,7 +105,7 @@ export class RadialMenu extends React.Component {
@observable private _pageX: number = 0;
@observable private _pageY: number = 0;
- @observable private _display: boolean = false;
+ @observable _display: boolean = false;
@observable private _yRelativeToTop: boolean = true;
@@ -124,35 +131,34 @@ export class RadialMenu extends React.Component {
displayMenu = (x: number, y: number) => {
//maxX and maxY will change if the UI/font size changes, but will work for any amount
//of items added to the menu
-
- this._pageX = x;
- this._pageY = y;
+ this._mouseX = x;
+ this._mouseY = y;
this._shouldDisplay = true;
}
-
- get pageX() {
- const x = this._pageX;
- if (x < 0) {
- return 0;
- }
- const width = this._width;
- if (x + width > window.innerWidth - RadialMenu.buffer) {
- return window.innerWidth - RadialMenu.buffer - width;
- }
- return x;
- }
-
- get pageY() {
- const y = this._pageY;
- if (y < 0) {
- return 0;
- }
- const height = this._height;
- if (y + height > window.innerHeight - RadialMenu.buffer) {
- return window.innerHeight - RadialMenu.buffer - height;
- }
- return y;
- }
+ // @computed
+ // get pageX() {
+ // const x = this._pageX;
+ // if (x < 0) {
+ // return 0;
+ // }
+ // const width = this._width;
+ // if (x + width > window.innerWidth - RadialMenu.buffer) {
+ // return window.innerWidth - RadialMenu.buffer - width;
+ // }
+ // return x;
+ // }
+ // @computed
+ // get pageY() {
+ // const y = this._pageY;
+ // if (y < 0) {
+ // return 0;
+ // }
+ // const height = this._height;
+ // if (y + height > window.innerHeight - RadialMenu.buffer) {
+ // return window.innerHeight - RadialMenu.buffer - height;
+ // }
+ // return y;
+ // }
@computed get menuItems() {
return this._items.map((item, index) => <RadialMenuItem {...item} key={item.description} closeMenu={this.closeMenu} max={this._items.length} min={index} selected={this._closest} />);
@@ -166,7 +172,10 @@ export class RadialMenu extends React.Component {
}
@action
- openMenu = () => {
+ openMenu = (x: number, y: number) => {
+
+ this._pageX = x;
+ this._pageY = y;
this._shouldDisplay;
this._display = true;
}
@@ -207,12 +216,12 @@ export class RadialMenu extends React.Component {
if (!this._display) {
return null;
}
- const style = this._yRelativeToTop ? { left: this._mouseX - 150, top: this._mouseY - 150 } :
- { left: this._mouseX - 150, top: this._mouseY - 150 };
+ const style = this._yRelativeToTop ? { left: this._pageX - 130, top: this._pageY - 130 } :
+ { left: this._pageX - 130, top: this._pageY - 130 };
return (
- <div className="radialMenu-cont" style={style}>
+ <div className="radialMenu-cont" onTouchStart={this.catchTouch} style={style}>
<canvas id="newCanvas" style={{ position: "absolute" }} height="300" width="300"> Your browser does not support the HTML5 canvas tag.</canvas>
{this.menuItems}
</div>