aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/Touchable.tsx2
-rw-r--r--src/client/views/nodes/DocumentView.tsx91
-rw-r--r--src/client/views/nodes/RadialMenu.tsx132
-rw-r--r--src/client/views/nodes/RadialMenuItem.tsx146
4 files changed, 156 insertions, 215 deletions
diff --git a/src/client/views/Touchable.tsx b/src/client/views/Touchable.tsx
index 49b2116f1..7d9184bea 100644
--- a/src/client/views/Touchable.tsx
+++ b/src/client/views/Touchable.tsx
@@ -137,11 +137,9 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
}
handle1PointerHoldStart = (e: React.TouchEvent): any => {
- console.log("Hold");
e.stopPropagation();
e.preventDefault();
document.removeEventListener("touchmove", this.onTouch);
- document.removeEventListener("touchend", this.onTouchEnd);
}
} \ No newline at end of file
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 49d35637e..e6c6aaa08 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -107,33 +107,38 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
@computed get nativeHeight() { return this.layoutDoc.nativeHeight || 0; }
@computed get onClickHandler() { return this.props.onClick ? this.props.onClick : this.Document.onClick; }
- private _firstX:number=0;
- private _firstY:number=0;
+ private _firstX: number = 0;
+ private _firstY: number = 0;
-
- handle1PointerHoldStart= (e: React.TouchEvent): any =>{
+
+ handle1PointerHoldStart = (e: React.TouchEvent): any => {
this.onRadialMenu(e);
- let page =e.touches[0];
- this._firstX=page.pageX;
- this._firstY=page.pageY;
+ const pt = InteractionUtils.GetMyTargetTouches(e, this.prevPoints)[0];
+ this._firstX = pt.pageX;
+ this._firstY = pt.pageY;
+ e.stopPropagation();
+ e.preventDefault();
document.removeEventListener("touchmove", this.onTouch);
- document.removeEventListener("touchend", this.onTouchEnd);
+ document.removeEventListener("touchmove", this.handle1PointerHoldMove);
document.addEventListener("touchmove", this.handle1PointerHoldMove);
+ document.removeEventListener("touchend", this.handle1PointerHoldEnd);
document.addEventListener("touchend", this.handle1PointerHoldEnd);
}
- handle1PointerHoldMove = (event: TouchEvent): void => {
- let e=event.touches[0];
- Math.abs(e.pageX-this._firstX)>150 ||Math.abs(e.pageY-this._firstY)>150? this.handleRelease():null;
+ handle1PointerHoldMove = (e: TouchEvent): void => {
+ const pt = InteractionUtils.GetMyTargetTouches(e, this.prevPoints)[0];
+ if (Math.abs(pt.pageX - this._firstX) > 150 || Math.abs(pt.pageY - this._firstY) > 150) {
+ this.handleRelease();
+ }
document.removeEventListener("touchmove", this.handle1PointerHoldMove);
document.addEventListener("touchmove", this.handle1PointerHoldMove);
document.removeEventListener("touchend", this.handle1PointerHoldEnd);
document.addEventListener("touchend", this.handle1PointerHoldEnd);
}
- handleRelease(){
- RadialMenu.Instance.closeMenu()
+ handleRelease() {
+ RadialMenu.Instance.closeMenu();
document.removeEventListener("touchmove", this.handle1PointerHoldMove);
document.removeEventListener("touchend", this.handle1PointerHoldEnd);
}
@@ -145,56 +150,24 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
}
@action
- onRadialMenu = async (event: React.TouchEvent): Promise<void> => {
- // the touch onContextMenu is button 0, the pointer onContextMenu is button 2
- // if (e.button === 0) {
- // e.preventDefault();
- // return;
- // }
- let e = event.touches[0];
- // if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3 ||
- // // event.isDefaultPrevented()) {
- // // event.preventDefault();
- // return;
- // }
- // event.preventDefault();
-
- let rm = RadialMenu.Instance;
- rm.openMenu();
- const one = RadialMenu.Instance.findByDescription("one...");
- const two = RadialMenu.Instance.findByDescription("two...");
- const three = RadialMenu.Instance.findByDescription("three...");
- const four= RadialMenu.Instance.findByDescription("four...");
- // const five= RadialMenu.Instance.findByDescription("five...");
- // const six= RadialMenu.Instance.findByDescription("six...");
- // const seven= RadialMenu.Instance.findByDescription("seven...");
-
-
- !one?rm.addItem({ description: "one one one one one one one one one", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { width: 300, height: 300 }), undefined, "onRight"), icon: "layer-group",selected:-1 }):null;
- !two?rm.addItem({ description: "two", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { width: 300, height: 300 }), undefined, "onRight"), icon: "layer-group",selected:-1 }):null;
- !three?rm.addItem({ description: "three", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { width: 300, height: 300 }), undefined, "onRight"), icon: "layer-group",selected:-1 }):null;
- !four?rm.addItem({ description: "four", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { width: 300, height: 300 }), undefined, "onRight"), icon: "layer-group",selected:-1 }):null;
- // !five?rm.addItem({ description: "five", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { width: 300, height: 300 }), undefined, "onRight"), icon: "layer-group",selected:-1 }):null;
+ onRadialMenu = (e: React.TouchEvent): void => {
+ const pt = InteractionUtils.GetMyTargetTouches(e, this.prevPoints)[0];
+
+ 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: "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: "tab", selected: -1 });
+ RadialMenu.Instance.addItem({ description: "four", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { width: 300, height: 300 }), undefined, "onRight"), icon: "layer-group", selected: -1 });
// !six?rm.addItem({ description: "six", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { width: 300, height: 300 }), undefined, "onRight"), icon: "layer-group" ,selected:-1}):null;
// !seven?rm.addItem({ description: "seven", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { width: 300, height: 300 }), undefined, "onRight"), icon: "layer-group" ,selected:-1}):null;
- runInAction(() => {
- // cm.addItem({
- // description: "Share",
- // event: () => SharingManager.Instance.open(this),
- // icon: "external-link-alt"
- // });
-
- if (!this.topMost) {
- // DocumentViews should stop propagation of this event
- }
- RadialMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
- if (!SelectionManager.IsSelected(this, true)) {
- SelectionManager.SelectDoc(this, false);
- }
- });
+ RadialMenu.Instance.displayMenu(pt.pageX - 15, pt.pageY - 15);
+ if (!SelectionManager.IsSelected(this, true)) {
+ SelectionManager.SelectDoc(this, false);
+ }
}
-
+
@action
componentDidMount() {
this._mainCont.current && (this._dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, this.drop.bind(this)));
diff --git a/src/client/views/nodes/RadialMenu.tsx b/src/client/views/nodes/RadialMenu.tsx
index d8750a192..74c5f53bd 100644
--- a/src/client/views/nodes/RadialMenu.tsx
+++ b/src/client/views/nodes/RadialMenu.tsx
@@ -1,13 +1,11 @@
import React = require("react");
import { observer } from "mobx-react";
import { action, observable, computed, IReactionDisposer, reaction, runInAction } from "mobx";
-import { RadialMenuItem, RadialMenuProps, OriginalMenuProps } from "./RadialMenuItem";
+import { RadialMenuItem, RadialMenuProps } from "./RadialMenuItem";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import Measure from "react-measure";
import "./RadialMenu.scss";
-
-
@observer
export class RadialMenu extends React.Component {
static Instance: RadialMenu;
@@ -30,36 +28,36 @@ export class RadialMenu extends React.Component {
onPointerDown = (e: PointerEvent) => {
this._mouseDown = true;
this._mouseX = e.clientX;
- this._mouseY = e.clientY;
+ this._mouseY = e.clientY;
document.addEventListener("pointermove", this.onPointerMove);
}
- @observable
- private _closest:number=-1;
+ @observable
+ private _closest: number = -1;
@action
onPointerMove = (e: PointerEvent) => {
const curX = e.clientX;
const curY = e.clientY;
- const deltX = this._mouseX-curX
- const deltY = this._mouseY-curY
- const scale = Math.hypot(deltY,deltX)
+ 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;
+ if (scale < 150 && scale > 50) {
+ const rad = Math.atan2(deltY, deltX) + Math.PI;
+ let closest = 0;
let closestval = 999999999;
- for (let x =0; x<this._items.length; x++){
- let curmin= (x/this._items.length)*2*Math.PI;
- if (rad-curmin<closestval && rad-curmin>0){
- closestval=rad-curmin
- closest=x;
+ for (let x = 0; x < this._items.length; x++) {
+ const curmin = (x / this._items.length) * 2 * Math.PI;
+ if (rad - curmin < closestval && rad - curmin > 0) {
+ closestval = rad - curmin;
+ closest = x;
}
}
- this._closest=closest;
+ this._closest = closest;
}
- else{
- this._closest=-1;
+ else {
+ this._closest = -1;
}
}
@action
@@ -72,8 +70,8 @@ export class RadialMenu extends React.Component {
}
this._shouldDisplay && (this._display = true);
document.removeEventListener("pointermove", this.onPointerMove);
- if (this._closest!==-1){
- this._items[this._closest].event();
+ if (this._closest !== -1) {
+ this._items[this._closest]?.event();
}
}
componentWillUnmount() {
@@ -94,7 +92,7 @@ export class RadialMenu extends React.Component {
);
}
- componentDidUpdate = () =>{
+ componentDidUpdate = () => {
this.previewcircle();
}
@@ -112,23 +110,14 @@ export class RadialMenu extends React.Component {
return this._items;
}
- findByDescription = (target: string, toLowerCase = false) => {
- return this._items.find(menuItem => {
- let reference = menuItem.description;
- toLowerCase && (reference = reference.toLowerCase());
- return reference === target;
- });
- }
-
-
@action
addItem(item: RadialMenuProps) {
if (this._items.indexOf(item) === -1) {
this._items.push(item);
}
}
-
- @observable
+
+ @observable
private _items: Array<RadialMenuProps> = [];
@action
@@ -166,7 +155,7 @@ export class RadialMenu extends React.Component {
}
@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} />);
+ return this._items.map((item, index) => <RadialMenuItem {...item} key={item.description} closeMenu={this.closeMenu} max={this._items.length} min={index} selected={this._closest} />);
}
@action
@@ -188,60 +177,45 @@ export class RadialMenu extends React.Component {
}
- previewcircle(){
- if (document.getElementById("newCanvas")!==null){
- var c : any= document.getElementById("newCanvas");
- if (c.getContext){
- var ctx = c.getContext("2d");
- ctx.beginPath();
- ctx.arc(150, 150, 50, 0, 2 * Math.PI);
- ctx.fillStyle="white";
- ctx.fill()
- ctx.font = "12px Arial";
- ctx.fillStyle = "black";
- ctx.textAlign = "center";
- let description ="";
- if (this._closest!==-1){
- description = this._items[this._closest].description;
- }
- if (description.length>15){
- description= description.slice(0,12);
- description += "...";
- }
- ctx.fillText(description, 150, 150, 90);
+ previewcircle() {
+ if (document.getElementById("newCanvas") !== null) {
+ const c: any = document.getElementById("newCanvas");
+ if (c.getContext) {
+ const ctx = c.getContext("2d");
+ ctx.beginPath();
+ ctx.arc(150, 150, 50, 0, 2 * Math.PI);
+ ctx.fillStyle = "white";
+ ctx.fill();
+ ctx.font = "12px Arial";
+ ctx.fillStyle = "black";
+ ctx.textAlign = "center";
+ let description = "";
+ if (this._closest !== -1) {
+ description = this._items[this._closest].description;
+ }
+ if (description.length > 15) {
+ description = description.slice(0, 12);
+ description += "...";
+ }
+ ctx.fillText(description, 150, 150, 90);
+ }
}
}
- }
-
+
render() {
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._mouseX - 150, top: this._mouseY - 150 } :
+ { left: this._mouseX - 150, top: this._mouseY - 150 };
- const contents = (
- <>
- {this.menuItems}
- </>
- );
- // return (
- // <Measure offset onResize={action((r: any) => { this._width = r.offset.width; this._height = r.offset.height; })}>
- // {({ measureRef }) => (
- // <div className="radialMenu-cont" style={style} ref={measureRef}>
- // {contents}
- // </div>
- // )
- // }
- // </Measure>
- // );
return (
- <div className="radialMenu-cont" style={style}>
- <canvas id="newCanvas" style={{position:"absolute"}}height="300" width="300"> Your browser does not support the HTML5 canvas tag.</canvas>
- {contents}
- </div>
+ <div className="radialMenu-cont" 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>
);
}
diff --git a/src/client/views/nodes/RadialMenuItem.tsx b/src/client/views/nodes/RadialMenuItem.tsx
index 4ca257df5..fdc732d3f 100644
--- a/src/client/views/nodes/RadialMenuItem.tsx
+++ b/src/client/views/nodes/RadialMenuItem.tsx
@@ -8,114 +8,110 @@ import { UndoManager } from "../../util/UndoManager";
library.add(faAngleRight);
-export interface OriginalMenuProps {
+export interface RadialMenuProps {
description: string;
event: (stuff?: any) => void;
undoable?: boolean;
icon: IconProp;
closeMenu?: () => void;
min?: number;
- max?:number;
- selected:number;
+ max?: number;
+ selected: number;
}
-export type RadialMenuProps = OriginalMenuProps;
-
@observer
-export class RadialMenuItem extends React.Component<RadialMenuProps & { selected?: boolean }> {
+export class RadialMenuItem extends React.Component<RadialMenuProps> {
- componentDidMount = () =>{
+ componentDidMount = () => {
this.setcircle();
}
- componentDidUpdate = () =>{
+ componentDidUpdate = () => {
this.setcircle();
}
- handleEvent = async (e: React.MouseEvent<HTMLDivElement>) => {
- if ("event" in this.props) {
- this.props.closeMenu && this.props.closeMenu();
- let batch: UndoManager.Batch | undefined;
- if (this.props.undoable !== false) {
- batch = UndoManager.StartBatch(`Context menu event: ${this.props.description}`);
- }
- await this.props.event({ x: e.clientX, y: e.clientY });
- batch && batch.end();
+ handleEvent = async (e: React.PointerEvent) => {
+ this.props.closeMenu && this.props.closeMenu();
+ let batch: UndoManager.Batch | undefined;
+ if (this.props.undoable !== false) {
+ batch = UndoManager.StartBatch(`Context menu event: ${this.props.description}`);
}
+ await this.props.event({ x: e.clientX, y: e.clientY });
+ batch && batch.end();
}
- setcircle(){
- let circlemin=0;
- let circlemax=1
- this.props.min? circlemin=this.props.min:null;
- this.props.max? circlemax=this.props.max:null;
- if (document.getElementById("myCanvas")!==null){
- var c : any= document.getElementById("myCanvas");
- let color = "white"
- switch(circlemin%3){
- case 1:
+ setcircle() {
+ let circlemin = 0;
+ let circlemax = 1
+ this.props.min ? circlemin = this.props.min : null;
+ this.props.max ? circlemax = this.props.max : null;
+ if (document.getElementById("myCanvas") !== null) {
+ var c: any = document.getElementById("myCanvas");
+ let color = "white"
+ switch (circlemin % 3) {
+ case 1:
+ color = "#c2c2c5";
+ break;
+ case 0:
+ color = "#f1efeb";
+ break;
+ case 2:
+ color = "lightgray";
+ break;
+ }
+ if (circlemax % 3 === 1 && circlemin === circlemax - 1) {
color = "#c2c2c5";
- break;
- case 0:
- color = "#f1efeb";
- break;
- case 2:
- color = "lightgray";
- break;
- }
- if (circlemax%3===1 && circlemin===circlemax-1){
- color="#c2c2c5";
- }
+ }
- if (this.props.selected === this.props.min){
- color="#808080";
-
- }
- if (c.getContext){
- var ctx = c.getContext("2d");
- ctx.beginPath();
- ctx.arc(150, 150, 150, (circlemin/circlemax)*2*Math.PI, ((circlemin+1)/circlemax) * 2 * Math.PI);
- ctx.arc(150, 150, 50, ((circlemin+1)/circlemax)*2*Math.PI, (circlemin/circlemax) * 2 * Math.PI,true);
- ctx.fillStyle=color;
- ctx.fill()
+ if (this.props.selected === this.props.min) {
+ color = "#808080";
+
+ }
+ if (c.getContext) {
+ var ctx = c.getContext("2d");
+ ctx.beginPath();
+ ctx.arc(150, 150, 150, (circlemin / circlemax) * 2 * Math.PI, ((circlemin + 1) / circlemax) * 2 * Math.PI);
+ ctx.arc(150, 150, 50, ((circlemin + 1) / circlemax) * 2 * Math.PI, (circlemin / circlemax) * 2 * Math.PI, true);
+ ctx.fillStyle = color;
+ ctx.fill()
+ }
}
}
- }
- calculatorx(){
- let circlemin=0;
- let circlemax=1
- this.props.min? circlemin=this.props.min:null;
- this.props.max? circlemax=this.props.max:null;
- let avg = ((circlemin/circlemax)+((circlemin+1)/circlemax))/2;
- let degrees = 360*avg;
- let x= 100*Math.cos(degrees*Math.PI/180);
- let y =-125*Math.sin(degrees*Math.PI/180);
+ calculatorx() {
+ let circlemin = 0;
+ let circlemax = 1
+ this.props.min ? circlemin = this.props.min : null;
+ this.props.max ? circlemax = this.props.max : null;
+ let avg = ((circlemin / circlemax) + ((circlemin + 1) / circlemax)) / 2;
+ let degrees = 360 * avg;
+ let x = 100 * Math.cos(degrees * Math.PI / 180);
+ let y = -125 * Math.sin(degrees * Math.PI / 180);
return x;
}
- calculatory(){
-
- let circlemin=0;
- let circlemax=1
- this.props.min? circlemin=this.props.min:null;
- this.props.max? circlemax=this.props.max:null;
- let avg = ((circlemin/circlemax)+((circlemin+1)/circlemax))/2;
- let degrees = 360*avg;
- let x= 125*Math.cos(degrees*Math.PI/180);
- let y =-100*Math.sin(degrees*Math.PI/180);
+ calculatory() {
+
+ let circlemin = 0;
+ let circlemax = 1
+ this.props.min ? circlemin = this.props.min : null;
+ this.props.max ? circlemax = this.props.max : null;
+ let avg = ((circlemin / circlemax) + ((circlemin + 1) / circlemax)) / 2;
+ let degrees = 360 * avg;
+ let x = 125 * Math.cos(degrees * Math.PI / 180);
+ let y = -100 * Math.sin(degrees * Math.PI / 180);
return y;
}
render() {
- return (
- <div className={"radialMenu-item" + (this.props.selected ? " radialMenu-itemSelected" : "")} onClick={this.handleEvent}>
- <canvas id="myCanvas" height="300" width="300"> Your browser does not support the HTML5 canvas tag.</canvas>
- <FontAwesomeIcon icon={this.props.icon} size="3x" style={{ position:"absolute", left:this.calculatorx()+150-19, top:this.calculatory()+150-19}} />
- </div>
- );
+ return (
+ <div className={"radialMenu-item" + (this.props.selected ? " radialMenu-itemSelected" : "")} onPointerUp={this.handleEvent}>
+ <canvas id="myCanvas" height="300" width="300"> Your browser does not support the HTML5 canvas tag.</canvas>
+ <FontAwesomeIcon icon={this.props.icon} size="3x" style={{ position: "absolute", left: this.calculatorx() + 150 - 19, top: this.calculatory() + 150 - 19 }} />
+ </div>
+ );
}
} \ No newline at end of file