aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/GestureOverlay.tsx
diff options
context:
space:
mode:
authorBob Zeleznik <zzzman@gmail.com>2020-04-08 20:56:47 -0400
committerBob Zeleznik <zzzman@gmail.com>2020-04-08 20:56:47 -0400
commit051aefd6455ccda271377913a486e923aef40efd (patch)
treef33e1a52b72bf066e93415a12f47ed74a62f5b4a /src/client/views/GestureOverlay.tsx
parent9a795d09127d10f23e3992f899265fd227e49af4 (diff)
parentb21db9d40c1619df5455ba8ffe3ef76913cc92de (diff)
Merge branch 'master' into script_documents
Diffstat (limited to 'src/client/views/GestureOverlay.tsx')
-rw-r--r--src/client/views/GestureOverlay.tsx417
1 files changed, 341 insertions, 76 deletions
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index a8cf8c197..69aa8dbaa 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -2,49 +2,72 @@ import React = require("react");
import { Touchable } from "./Touchable";
import { observer } from "mobx-react";
import "./GestureOverlay.scss";
-import { computed, observable, action, runInAction, IReactionDisposer, reaction } from "mobx";
+import { computed, observable, action, runInAction, IReactionDisposer, reaction, flow, trace } from "mobx";
import { GestureUtils } from "../../pen-gestures/GestureUtils";
import { InteractionUtils } from "../util/InteractionUtils";
import { InkingControl } from "./InkingControl";
-import { InkTool } from "../../new_fields/InkField";
+import { InkTool, InkData } from "../../new_fields/InkField";
import { Doc } from "../../new_fields/Doc";
import { LinkManager } from "../util/LinkManager";
-import { DocUtils } from "../documents/Documents";
+import { DocUtils, Docs } from "../documents/Documents";
import { undoBatch } from "../util/UndoManager";
import { Scripting } from "../util/Scripting";
import { FieldValue, Cast, NumCast, BoolCast } from "../../new_fields/Types";
import { CurrentUserUtils } from "../../server/authentication/models/current_user_utils";
-import Palette from "./Palette";
-import { Utils, emptyPath, emptyFunction, returnFalse, returnOne, returnEmptyString, returnTrue, numberRange } from "../../Utils";
+import HorizontalPalette from "./Palette";
+import { Utils, emptyPath, emptyFunction, returnFalse, returnOne, returnEmptyString, returnTrue, numberRange, returnZero } from "../../Utils";
import { DocumentView } from "./nodes/DocumentView";
import { Transform } from "../util/Transform";
import { DocumentContentsView } from "./nodes/DocumentContentsView";
+import { CognitiveServices } from "../cognitive_services/CognitiveServices";
+import { DocServer } from "../DocServer";
+import htmlToImage from "html-to-image";
+import { ScriptField } from "../../new_fields/ScriptField";
+import { listSpec } from "../../new_fields/Schema";
+import { List } from "../../new_fields/List";
+import { CollectionViewType } from "./collections/CollectionView";
+import TouchScrollableMenu, { TouchScrollableMenuItem } from "./TouchScrollableMenu";
+import MobileInterface from "../../mobile/MobileInterface";
+import { MobileInkOverlayContent } from "../../server/Message";
+import MobileInkOverlay from "../../mobile/MobileInkOverlay";
+import { RadialMenu } from "./nodes/RadialMenu";
+import { SelectionManager } from "../util/SelectionManager";
+
@observer
export default class GestureOverlay extends Touchable {
static Instance: GestureOverlay;
- @observable public Color: string = "rgb(244, 67, 54)";
- @observable public Width: number = 5;
+ @observable public Color: string = "rgb(0, 0, 0)";
+ @observable public Width: number = 2;
@observable public SavedColor?: string;
@observable public SavedWidth?: number;
@observable public Tool: ToolglassTools = ToolglassTools.None;
@observable private _thumbX?: number;
@observable private _thumbY?: number;
+ @observable private _selectedIndex: number = -1;
+ @observable private _menuX: number = -300;
+ @observable private _menuY: number = -300;
@observable private _pointerY?: number;
@observable private _points: { X: number, Y: number }[] = [];
+ @observable private _strokes: InkData[] = [];
@observable private _palette?: JSX.Element;
@observable private _clipboardDoc?: JSX.Element;
+ @observable private _possibilities: JSX.Element[] = [];
- @computed private get height(): number { return Math.max(this._pointerY && this._thumbY ? this._thumbY - this._pointerY : 300, 300); }
+ @computed private get height(): number { return 2 * Math.max(this._pointerY && this._thumbY ? this._thumbY - this._pointerY : 100, 100); }
@computed private get showBounds() { return this.Tool !== ToolglassTools.None; }
+ @observable private showMobileInkOverlay: boolean = false;
+
private _d1: Doc | undefined;
+ private _inkToTextDoc: Doc | undefined;
private _thumbDoc: Doc | undefined;
private thumbIdentifier?: number;
private pointerIdentifier?: number;
private _hands: Map<number, React.Touch[]> = new Map<number, React.Touch[]>();
+ private _holdTimer: NodeJS.Timeout | undefined;
protected multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
@@ -54,6 +77,11 @@ export default class GestureOverlay extends Touchable {
GestureOverlay.Instance = this;
}
+ componentDidMount = () => {
+ this._thumbDoc = FieldValue(Cast(CurrentUserUtils.setupThumbDoc(CurrentUserUtils.UserDocument), Doc));
+ this._inkToTextDoc = FieldValue(Cast(this._thumbDoc?.inkToTextDoc, Doc));
+ }
+
getNewTouches(e: React.TouchEvent | TouchEvent) {
const ntt: (React.Touch | Touch)[] = Array.from(e.targetTouches);
const nct: (React.Touch | Touch)[] = Array.from(e.changedTouches);
@@ -84,6 +112,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);
@@ -107,8 +144,6 @@ export default class GestureOverlay extends Touchable {
ptsToDelete.forEach(pt => this.prevPoints.delete(pt));
const nts = this.getNewTouches(te);
- console.log(nts.nt.length);
-
if (nts.nt.length < 5) {
const target = document.elementFromPoint(te.changedTouches.item(0).clientX, te.changedTouches.item(0).clientY);
target?.dispatchEvent(
@@ -125,6 +160,41 @@ export default class GestureOverlay extends Touchable {
}
)
);
+ 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);
+ const 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 {
+ this._holdTimer && clearTimeout(this._holdTimer);
+ }
document.removeEventListener("touchmove", this.onReactTouchMove);
document.removeEventListener("touchend", this.onReactTouchEnd);
document.addEventListener("touchmove", this.onReactTouchMove);
@@ -137,8 +207,72 @@ 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);
+ }
+ document.dispatchEvent(
+ new CustomEvent<InteractionUtils.MultiTouchEvent<TouchEvent>>("dashOnTouchHoldMove",
+ {
+ bubbles: true,
+ detail: {
+ fingers: this.prevPoints.size,
+ targetTouches: nts.ntt,
+ touches: nts.nt,
+ changedTouches: nts.nct,
+ touchEvent: e
+ }
+ })
+ );
+ }
+
+ onReactHoldTouchEnd = (e: TouchEvent) => {
+ 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>>("dashOnTouchHoldEnd",
+ {
+ bubbles: true,
+ detail: {
+ fingers: this.prevPoints.size,
+ targetTouches: nts.ntt,
+ touches: nts.nt,
+ changedTouches: nts.nct,
+ touchEvent: e
+ }
+ })
+ );
+ for (let i = 0; i < e.changedTouches.length; i++) {
+ const pt = e.changedTouches.item(i);
+ if (pt) {
+ if (this.prevPoints.has(pt.identifier)) {
+ this.prevPoints.delete(pt.identifier);
+ }
+ }
+ }
+
+ document.removeEventListener("touchmove", this.onReactHoldTouchMove);
+ document.removeEventListener("touchend", this.onReactHoldTouchEnd);
+
+ e.stopPropagation();
+ }
+
+
onReactTouchMove = (e: TouchEvent) => {
const nts: any = this.getNewTouches(e);
+ this._holdTimer && clearTimeout(this._holdTimer);
+ this._holdTimer = undefined;
+
document.dispatchEvent(
new CustomEvent<InteractionUtils.MultiTouchEvent<TouchEvent>>("dashOnTouchMove",
{
@@ -156,6 +290,9 @@ export default class GestureOverlay extends Touchable {
onReactTouchEnd = (e: TouchEvent) => {
const nts: any = this.getNewTouches(e);
+ this._holdTimer && clearTimeout(this._holdTimer);
+ this._holdTimer = undefined;
+
document.dispatchEvent(
new CustomEvent<InteractionUtils.MultiTouchEvent<TouchEvent>>("dashOnTouchEnd",
{
@@ -186,6 +323,7 @@ export default class GestureOverlay extends Touchable {
}
handleHandDown = async (e: React.TouchEvent) => {
+ this._holdTimer && 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);
@@ -216,13 +354,16 @@ export default class GestureOverlay extends Touchable {
console.log("not hand");
}
this.pointerIdentifier = pointer?.identifier;
- runInAction(() => this._pointerY = pointer?.clientY);
- if (thumb.identifier === this.thumbIdentifier) {
- this._thumbX = thumb.clientX;
- this._thumbY = thumb.clientY;
- this._hands.set(thumb.identifier, fingers);
- return;
- }
+ runInAction(() => {
+ this._pointerY = pointer?.clientY;
+ if (thumb.identifier === this.thumbIdentifier) {
+ this._thumbX = thumb.clientX;
+ this._thumbY = thumb.clientY;
+ this._hands.set(thumb.identifier, fingers);
+ return;
+ }
+ });
+
this.thumbIdentifier = thumb?.identifier;
this._hands.set(thumb.identifier, fingers);
const others = fingers.filter(f => f !== thumb);
@@ -232,10 +373,14 @@ 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;
this._thumbY = thumb.clientY;
- this._palette = <Palette x={minX} y={minY} thumb={[thumb.clientX, thumb.clientY]} thumbDoc={thumbDoc} />;
+ this._menuX = thumb.clientX + 50;
+ this._menuY = thumb.clientY;
+ this._palette = <HorizontalPalette x={minX} y={minY} thumb={[thumb.clientX, thumb.clientY]} thumbDoc={thumbDoc} />;
});
}
@@ -273,11 +418,33 @@ export default class GestureOverlay extends Touchable {
for (let i = 0; i < e.changedTouches.length; i++) {
const pt = e.changedTouches.item(i);
- if (pt && pt.identifier === this.thumbIdentifier && this._thumbX && this._thumbDoc) {
- if (Math.abs(pt.clientX - this._thumbX) > 20) {
- this._thumbDoc.selectedIndex = Math.max(0, NumCast(this._thumbDoc.selectedIndex) - Math.sign(pt.clientX - this._thumbX));
- this._thumbX = pt.clientX;
+ if (pt && pt.identifier === this.thumbIdentifier && this._thumbY) {
+ if (this._thumbX && this._thumbY) {
+ const yOverX = Math.abs(pt.clientX - this._thumbX) < Math.abs(pt.clientY - this._thumbY);
+ if ((yOverX && this._inkToTextDoc) || this._selectedIndex > -1) {
+ if (Math.abs(pt.clientY - this._thumbY) > (10 * window.devicePixelRatio)) {
+ this._selectedIndex = Math.min(Math.max(-1, (-Math.ceil((pt.clientY - this._thumbY) / (10 * window.devicePixelRatio)) - 1)), this._possibilities.length - 1);
+ }
+ }
+ else if (this._thumbDoc) {
+ if (Math.abs(pt.clientX - this._thumbX) > (15 * window.devicePixelRatio)) {
+ this._thumbDoc.selectedIndex = Math.max(-1, NumCast(this._thumbDoc.selectedIndex) - Math.sign(pt.clientX - this._thumbX));
+ this._thumbX = pt.clientX;
+ }
+ }
}
+
+ // if (this._thumbX && this._thumbDoc) {
+ // if (Math.abs(pt.clientX - this._thumbX) > 30) {
+ // this._thumbDoc.selectedIndex = Math.max(0, NumCast(this._thumbDoc.selectedIndex) - Math.sign(pt.clientX - this._thumbX));
+ // this._thumbX = pt.clientX;
+ // }
+ // }
+ // if (this._thumbY && this._inkToTextDoc) {
+ // if (Math.abs(pt.clientY - this._thumbY) > 20) {
+ // this._selectedIndex = Math.min(Math.max(0, -Math.ceil((pt.clientY - this._thumbY) / 20)), this._possibilities.length - 1);
+ // }
+ // }
}
if (pt && pt.identifier === this.pointerIdentifier) {
this._pointerY = pt.clientY;
@@ -293,6 +460,24 @@ export default class GestureOverlay extends Touchable {
this._palette = undefined;
this.thumbIdentifier = undefined;
this._thumbDoc = undefined;
+
+ let scriptWorked = false;
+ if (NumCast(this._inkToTextDoc?.selectedIndex) > -1) {
+ const selectedButton = this._possibilities[this._selectedIndex];
+ if (selectedButton) {
+ selectedButton.props.onClick();
+ scriptWorked = true;
+ }
+ }
+
+ if (!scriptWorked) {
+ this._strokes.forEach(s => {
+ this.dispatchGesture(GestureUtils.Gestures.Stroke, s);
+ });
+ }
+ this._strokes = [];
+ this._points = [];
+ this._possibilities = [];
document.removeEventListener("touchend", this.handleHandUp);
}
}
@@ -317,6 +502,22 @@ export default class GestureOverlay extends Touchable {
this._points.push({ X: e.clientX, Y: e.clientY });
e.stopPropagation();
e.preventDefault();
+
+
+ if (this._points.length > 1) {
+ const B = this.svgBounds;
+ const initialPoint = this._points[0.];
+ const xInGlass = initialPoint.X > (this._thumbX ?? Number.MAX_SAFE_INTEGER) && initialPoint.X < (this._thumbX ?? Number.MAX_SAFE_INTEGER) + this.height;
+ const yInGlass = initialPoint.Y > (this._thumbY ?? Number.MAX_SAFE_INTEGER) - this.height && initialPoint.Y < (this._thumbY ?? Number.MAX_SAFE_INTEGER);
+ if (this.Tool !== ToolglassTools.None && xInGlass && yInGlass) {
+ switch (this.Tool) {
+ case ToolglassTools.RadialMenu:
+ document.removeEventListener("pointermove", this.onPointerMove);
+ document.removeEventListener("pointerup", this.onPointerUp);
+ //this.handle1PointerHoldStart(e);
+ }
+ }
+ }
}
}
@@ -333,8 +534,10 @@ export default class GestureOverlay extends Touchable {
this._d1 = doc;
}
else if (this._d1 !== doc && !LinkManager.Instance.doesLinkExist(this._d1, doc)) {
- DocUtils.MakeLink({ doc: this._d1 }, { doc: doc }, "gestural link");
- actionPerformed = true;
+ if (this._d1.type !== "ink" && doc.type !== "ink") {
+ DocUtils.MakeLink({ doc: this._d1 }, { doc: doc }, "gestural link");
+ actionPerformed = true;
+ }
}
};
const ge = new CustomEvent<GestureUtils.GestureEvent>("dashOnGesture",
@@ -358,12 +561,51 @@ export default class GestureOverlay extends Touchable {
const B = this.svgBounds;
const points = this._points.map(p => ({ X: p.X - B.left, Y: p.Y - B.top }));
- const xInGlass = points[0].X > (this._thumbX ?? Number.MAX_SAFE_INTEGER) && points[0].X < (this._thumbX ?? Number.MAX_SAFE_INTEGER) + this.height;
- const yInGlass = points[0].Y > (this._thumbY ?? Number.MAX_SAFE_INTEGER) - this.height && points[0].Y < (this._thumbY ?? Number.MAX_SAFE_INTEGER);
+ if (MobileInterface.Instance && MobileInterface.Instance.drawingInk) {
+ const { selectedColor, selectedWidth } = InkingControl.Instance;
+ DocServer.Mobile.dispatchGesturePoints({
+ points: this._points,
+ bounds: B,
+ color: selectedColor,
+ width: selectedWidth
+ });
+ }
+
+ const initialPoint = this._points[0.];
+ const xInGlass = initialPoint.X > (this._thumbX ?? Number.MAX_SAFE_INTEGER) && initialPoint.X < (this._thumbX ?? Number.MAX_SAFE_INTEGER) + (this.height);
+ const yInGlass = initialPoint.Y > (this._thumbY ?? Number.MAX_SAFE_INTEGER) - (this.height) && initialPoint.Y < (this._thumbY ?? Number.MAX_SAFE_INTEGER);
if (this.Tool !== ToolglassTools.None && xInGlass && yInGlass) {
switch (this.Tool) {
case ToolglassTools.InkToText:
+ document.removeEventListener("pointermove", this.onPointerMove);
+ document.removeEventListener("pointerup", this.onPointerUp);
+ this._strokes.push(new Array(...this._points));
+ this._points = [];
+ CognitiveServices.Inking.Appliers.InterpretStrokes(this._strokes).then((results) => {
+ console.log(results);
+ const wordResults = results.filter((r: any) => r.category === "line");
+ const possibilities: string[] = [];
+ for (const wR of wordResults) {
+ console.log(wR);
+ if (wR?.recognizedText) {
+ possibilities.push(wR?.recognizedText);
+ }
+ possibilities.push(...wR?.alternates?.map((a: any) => a.recognizedString));
+ }
+ console.log(possibilities);
+ const r = Math.max(this.svgBounds.right, ...this._strokes.map(s => this.getBounds(s).right));
+ const l = Math.min(this.svgBounds.left, ...this._strokes.map(s => this.getBounds(s).left));
+ const t = Math.min(this.svgBounds.top, ...this._strokes.map(s => this.getBounds(s).top));
+ runInAction(() => {
+ this._possibilities = possibilities.map(p =>
+ <TouchScrollableMenuItem text={p} onClick={() => GestureOverlay.Instance.dispatchGesture(GestureUtils.Gestures.Text, [{ X: l, Y: t }], p)} />);
+ });
+ });
+ break;
+ case ToolglassTools.IgnoreGesture:
+ this.dispatchGesture(GestureUtils.Gestures.Stroke);
+ this._points = [];
break;
}
}
@@ -373,16 +615,15 @@ export default class GestureOverlay extends Touchable {
if (result && result.Score > 0.7) {
switch (result.Name) {
case GestureUtils.Gestures.Box:
- const target = document.elementFromPoint(this._points[0].X, this._points[0].Y);
- target?.dispatchEvent(new CustomEvent<GestureUtils.GestureEvent>("dashOnGesture",
- {
- bubbles: true,
- detail: {
- points: this._points,
- gesture: GestureUtils.Gestures.Box,
- bounds: B
- }
- }));
+ this.dispatchGesture(GestureUtils.Gestures.Box);
+ actionPerformed = true;
+ break;
+ case GestureUtils.Gestures.StartBracket:
+ this.dispatchGesture(GestureUtils.Gestures.StartBracket);
+ actionPerformed = true;
+ break;
+ case GestureUtils.Gestures.EndBracket:
+ this.dispatchGesture("endbracket");
actionPerformed = true;
break;
case GestureUtils.Gestures.Line:
@@ -398,19 +639,7 @@ export default class GestureOverlay extends Touchable {
}
if (!actionPerformed) {
- const target = document.elementFromPoint(this._points[0].X, this._points[0].Y);
- target?.dispatchEvent(
- new CustomEvent<GestureUtils.GestureEvent>("dashOnGesture",
- {
- bubbles: true,
- detail: {
- points: this._points,
- gesture: GestureUtils.Gestures.Stroke,
- bounds: B
- }
- }
- )
- );
+ this.dispatchGesture(GestureUtils.Gestures.Stroke);
this._points = [];
}
}
@@ -419,9 +648,26 @@ export default class GestureOverlay extends Touchable {
document.removeEventListener("pointerup", this.onPointerUp);
}
- @computed get svgBounds() {
- const xs = this._points.map(p => p.X);
- const ys = this._points.map(p => p.Y);
+ dispatchGesture = (gesture: "box" | "line" | "startbracket" | "endbracket" | "stroke" | "scribble" | "text", stroke?: InkData, data?: any) => {
+ const target = document.elementFromPoint((stroke ?? this._points)[0].X, (stroke ?? this._points)[0].Y);
+ target?.dispatchEvent(
+ new CustomEvent<GestureUtils.GestureEvent>("dashOnGesture",
+ {
+ bubbles: true,
+ detail: {
+ points: stroke ?? this._points,
+ gesture: gesture as any,
+ bounds: this.getBounds(stroke ?? this._points),
+ text: data
+ }
+ }
+ )
+ );
+ }
+
+ getBounds = (stroke: InkData) => {
+ const xs = stroke.map(p => p.X);
+ const ys = stroke.map(p => p.Y);
const right = Math.max(...xs);
const left = Math.min(...xs);
const bottom = Math.max(...ys);
@@ -429,28 +675,28 @@ export default class GestureOverlay extends Touchable {
return { right: right, left: left, bottom: bottom, top: top, width: right - left, height: bottom - top };
}
- @computed get currentStroke() {
- if (this._points.length <= 1) {
- return (null);
- }
-
- const B = this.svgBounds;
-
- return (
- <svg width={B.width} height={B.height} style={{ transform: `translate(${B.left}px, ${B.top}px)`, pointerEvents: "none", position: "absolute", zIndex: 30000 }}>
- {InteractionUtils.CreatePolyline(this._points, B.left, B.top, this.Color, this.Width)}
- </svg>
- );
+ @computed get svgBounds() {
+ return this.getBounds(this._points);
}
@computed get elements() {
+ const B = this.svgBounds;
return [
this.props.children,
this._palette,
- this.currentStroke
+ [this._strokes.map(l => {
+ const b = this.getBounds(l);
+ return <svg key={b.left} width={b.width} height={b.height} style={{ transform: `translate(${b.left}px, ${b.top}px)`, pointerEvents: "none", position: "absolute", zIndex: 30000 }}>
+ {InteractionUtils.CreatePolyline(l, b.left, b.top, GestureOverlay.Instance.Color, GestureOverlay.Instance.Width)}
+ </svg>;
+ }),
+ this._points.length <= 1 ? (null) : <svg width={B.width} height={B.height} style={{ transform: `translate(${B.left}px, ${B.top}px)`, pointerEvents: "none", position: "absolute", zIndex: 30000 }}>
+ {InteractionUtils.CreatePolyline(this._points, B.left, B.top, GestureOverlay.Instance.Color, GestureOverlay.Instance.Width)}
+ </svg>]
];
}
-
+ screenToLocalTransform = () => new Transform(-(this._thumbX ?? 0), -(this._thumbY ?? 0) + this.height, 1);
+ return300 = () => 300;
@action
public openFloatingDoc = (doc: Doc) => {
this._clipboardDoc =
@@ -460,13 +706,16 @@ export default class GestureOverlay extends Touchable {
LibraryPath={emptyPath}
addDocument={undefined}
addDocTab={returnFalse}
+ rootSelected={returnTrue}
pinToPres={emptyFunction}
onClick={undefined}
removeDocument={undefined}
- ScreenToLocalTransform={() => new Transform(-(this._thumbX ?? 0), -(this._thumbY ?? 0) + this.height, 1)}
+ ScreenToLocalTransform={this.screenToLocalTransform}
ContentScaling={returnOne}
- PanelWidth={() => 300}
- PanelHeight={() => 300}
+ PanelWidth={this.return300}
+ PanelHeight={this.return300}
+ NativeHeight={returnZero}
+ NativeWidth={returnZero}
renderDepth={0}
backgroundColor={returnEmptyString}
focus={emptyFunction}
@@ -475,8 +724,6 @@ export default class GestureOverlay extends Touchable {
bringToFront={emptyFunction}
ContainingCollectionView={undefined}
ContainingCollectionDoc={undefined}
- zoomToScale={emptyFunction}
- getScale={returnOne}
/>;
}
@@ -485,21 +732,28 @@ export default class GestureOverlay extends Touchable {
this._clipboardDoc = undefined;
}
+ @action
+ enableMobileInkOverlay = (content: MobileInkOverlayContent) => {
+ this.showMobileInkOverlay = content.enableOverlay;
+ }
+
render() {
return (
<div className="gestureOverlay-cont" onPointerDown={this.onPointerDown} onTouchStart={this.onReactTouchStart}>
+ {this.showMobileInkOverlay ? <MobileInkOverlay /> : <></>}
{this.elements}
+
<div className="clipboardDoc-cont" style={{
- transform: `translate(${this._thumbX}px, ${(this._thumbY ?? 0) - this.height}px)`,
height: this.height,
width: this.height,
pointerEvents: this._clipboardDoc ? "unset" : "none",
touchAction: this._clipboardDoc ? "unset" : "none",
+ transform: `translate(${this._thumbX}px, ${(this._thumbY || 0) - this.height} px)`,
}}>
{this._clipboardDoc}
</div>
<div className="filter-cont" style={{
- transform: `translate(${this._thumbX}px, ${(this._thumbY ?? 0) - this.height}px)`,
+ transform: `translate(${this._thumbX}px, ${(this._thumbY || 0) - this.height}px)`,
height: this.height,
width: this.height,
pointerEvents: "none",
@@ -507,12 +761,20 @@ export default class GestureOverlay extends Touchable {
display: this.showBounds ? "unset" : "none",
}}>
</div>
- </div >);
+ <TouchScrollableMenu options={this._possibilities} bounds={this.svgBounds} selectedIndex={this._selectedIndex} x={this._menuX} y={this._menuY} />
+ {/* <div className="pointerBubbles">
+ {this._pointers.map(p => <div className="bubble" style={{ translate: `transform(${p.clientX}px, ${p.clientY}px)` }}></div>)}
+ </div> */}
+ </div>);
}
}
+// export class
+
export enum ToolglassTools {
InkToText = "inktotext",
+ IgnoreGesture = "ignoregesture",
+ RadialMenu = "radialmenu",
None = "none",
}
@@ -530,7 +792,10 @@ Scripting.addGlobal(function setPen(width: any, color: any) {
});
Scripting.addGlobal(function resetPen() {
runInAction(() => {
- GestureOverlay.Instance.Color = GestureOverlay.Instance.SavedColor ?? "rgb(244, 67, 54)";
- GestureOverlay.Instance.Width = GestureOverlay.Instance.SavedWidth ?? 5;
+ GestureOverlay.Instance.Color = GestureOverlay.Instance.SavedColor ?? "rgb(0, 0, 0)";
+ GestureOverlay.Instance.Width = GestureOverlay.Instance.SavedWidth ?? 2;
});
+});
+Scripting.addGlobal(function createText(text: any, x: any, y: any) {
+ GestureOverlay.Instance.dispatchGesture("text", [{ X: x, Y: y }], text);
}); \ No newline at end of file