From 1007cfb325f2dcddc4365538e4b354d06eb85f2f Mon Sep 17 00:00:00 2001 From: Stanley Yip Date: Tue, 4 Feb 2020 18:12:47 -0500 Subject: ok so the toolglass is working, but it's super slow... i'll fix that later lol --- src/pen-gestures/GestureUtils.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'src/pen-gestures') diff --git a/src/pen-gestures/GestureUtils.ts b/src/pen-gestures/GestureUtils.ts index 4b5ad6684..4e3493c1c 100644 --- a/src/pen-gestures/GestureUtils.ts +++ b/src/pen-gestures/GestureUtils.ts @@ -6,18 +6,16 @@ import { Doc, WidthSym, HeightSym } from "../new_fields/Doc"; import { NumCast } from "../new_fields/Types"; import { CollectionFreeFormView } from "../client/views/collections/collectionFreeForm/CollectionFreeFormView"; import { Rect } from "react-measure"; +import { Scripting } from "../client/util/Scripting"; export namespace GestureUtils { - namespace GestureDataTypes { - export type BoxData = Array; - } - export class GestureEvent { constructor( readonly gesture: Gestures, readonly points: PointData[], readonly bounds: Rect, - readonly callbackFn?: Function + readonly callbackFn?: Function, + readonly text?: any ) { } } @@ -38,7 +36,8 @@ export namespace GestureUtils { Box = "box", Line = "line", Stroke = "stroke", - Scribble = "scribble" + Scribble = "scribble", + Text = "text" } export const GestureRecognizer = new NDollarRecognizer(false); -- cgit v1.2.3-70-g09d2 From 593016303351f365d6ae13413b72d77495ea6a03 Mon Sep 17 00:00:00 2001 From: Stanley Yip Date: Sat, 8 Feb 2020 14:35:20 -0500 Subject: syntax highlighting :) --- src/client/documents/Documents.ts | 1 + src/client/views/GestureOverlay.tsx | 22 +++++-- .../collectionFreeForm/CollectionFreeFormView.tsx | 74 +++++++++++++++++++++- .../collections/collectionFreeForm/MarqueeView.tsx | 24 +++++-- src/pen-gestures/GestureUtils.ts | 2 + src/pen-gestures/ndollar.ts | 11 +++- 6 files changed, 119 insertions(+), 15 deletions(-) (limited to 'src/pen-gestures') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 1c13eb079..81a6ff802 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -139,6 +139,7 @@ export interface DocumentOptions { letterSpacing?: string; // is linear view expanded flexDirection?: "unset" | "row" | "column" | "row-reverse" | "column-reverse"; selectedIndex?: number; + syntaxColor?: string; // can be applied to text for syntax highlighting all matches in the text } class EmptyBox { diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index e8262af1b..0b77b4b86 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -50,7 +50,7 @@ export default class GestureOverlay extends Touchable { @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 : 300, 300); } @computed private get showBounds() { return this.Tool !== ToolglassTools.None; } private _d1: Doc | undefined; @@ -408,8 +408,8 @@ export default class GestureOverlay extends Touchable { const points = this._points.map(p => ({ X: p.X - B.left, Y: p.Y - B.top })); 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); + 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) { @@ -450,6 +450,14 @@ export default class GestureOverlay extends Touchable { 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(GestureUtils.Gestures.EndBracket); + actionPerformed = true; + break; case GestureUtils.Gestures.Line: actionPerformed = this.handleLineGesture(); break; @@ -562,8 +570,8 @@ export default class GestureOverlay extends Touchable {
@@ -571,8 +579,8 @@ export default class GestureOverlay extends Touchable {
= new Map(); private _clusterDistance: number = 75; private _hitCluster = false; private _layoutComputeReaction: IReactionDisposer | undefined; @@ -411,11 +416,78 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { }); this.addDocument(Docs.Create.FreeformDocument(sel, { title: "nested collection", x: bounds.x, y: bounds.y, _width: bWidth, _height: bHeight, _panX: 0, _panY: 0 })); sel.forEach(d => this.props.removeDocument(d)); + e.stopPropagation(); + break; + case GestureUtils.Gestures.StartBracket: + const start = this.getTransform().transformPoint(Math.min(...ge.points.map(p => p.X)), Math.min(...ge.points.map(p => p.Y))); + this._inkToTextStartX = start[0]; + this._inkToTextStartY = start[1]; + console.log("start"); + break; + case GestureUtils.Gestures.EndBracket: + console.log("end"); + if (this._inkToTextStartX && this._inkToTextStartY) { + const end = this.getTransform().transformPoint(Math.max(...ge.points.map(p => p.X)), Math.max(...ge.points.map(p => p.Y))); + const setDocs = this.getActiveDocuments().filter(s => s.proto?.type === "text" && s.color); + const sets = setDocs.map((sd) => { + return Cast(sd.data, RichTextField)?.Text as string; + }); + if (sets.length && sets[0]) { + this._wordPalette.clear(); + const colors = setDocs.map(sd => FieldValue(sd.color) as string); + sets.forEach((st: string, i: number) => { + const words = st.split(","); + words.forEach(word => { + this._wordPalette.set(word, colors[i]); + }); + }); + } + const inks = this.getActiveDocuments().filter(doc => { + if (doc.type === "ink") { + const l = NumCast(doc.x); + const r = l + doc[WidthSym](); + const t = NumCast(doc.y); + const b = t + doc[HeightSym](); + const pass = !(this._inkToTextStartX! > r || end[0] < l || this._inkToTextStartY! > b || end[1] < t); + return pass; + } + return false; + }); + const inkFields = inks.map(i => Cast(i.data, InkField)); + CognitiveServices.Inking.Appliers.InterpretStrokes(inkFields.filter(i => i instanceof InkField).map(i => i!.inkData)).then((results) => { + const wordResults = results.filter((r: any) => r.category === "inkWord"); + console.log(wordResults); + for (const word of wordResults) { + const indices: number[] = word.strokeIds; + indices.forEach(i => { + const otherInks: Doc[] = []; + indices.forEach(i2 => i2 !== i && otherInks.push(inks[i2])); + inks[i].relatedInks = new List(otherInks); + const uniqueColors: string[] = []; + Array.from(this._wordPalette.values()).forEach(c => uniqueColors.indexOf(c) === -1 && uniqueColors.push(c)); + inks[i].alternativeColors = new List(uniqueColors); + if (this._wordPalette.has(word.recognizedText)) { + inks[i].color = this._wordPalette.get(word.recognizedText); + } + else { + for (const alt of word.alternates) { + if (this._wordPalette.has(alt.recognizedString)) { + inks[i].color = this._wordPalette.get(alt.recognizedString); + break; + } + } + } + }); + } + }); + this._inkToTextStartX = end[0]; + } break; case GestureUtils.Gestures.Text: if (ge.text) { const B = this.getTransform().transformPoint(ge.points[0].X, ge.points[0].Y); this.addDocument(Docs.Create.TextDocument(ge.text, { title: ge.text, x: B[0], y: B[1] })); + e.stopPropagation(); } } } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 112df8f05..19a71012a 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -20,6 +20,7 @@ import React = require("react"); import MarqueeOptionsMenu from "./MarqueeOptionsMenu"; import { SubCollectionViewProps } from "../CollectionSubView"; import { CognitiveServices } from "../../../cognitive_services/CognitiveServices"; +import { RichTextField } from "../../../../new_fields/RichTextField"; interface MarqueeViewProps { getContainerTransform: () => Transform; @@ -368,18 +369,29 @@ export class MarqueeView extends React.Component s.proto?.type === "ink"); - const sets = selected.filter(s => s.proto?.type === "text") - const inkFields = inks.map(i => FieldValue(Cast(i.data, InkField))); + const setDocs = selected.filter(s => s.proto?.type === "text" && s.color); + const sets = setDocs.map((sd) => { + return Cast(sd.data, RichTextField)?.Text as string; + }); + const colors = setDocs.map(sd => FieldValue(sd.color) as string); + const wordToColor = new Map(); + console.log(sets); + sets.forEach((st: string, i: number) => { + const words = st.split(","); + words.forEach(word => { + wordToColor.set(word, colors[i]); + }); + }); + const inkFields = inks.map(i => Cast(i.data, InkField)); CognitiveServices.Inking.Appliers.InterpretStrokes(inkFields.filter(i => i instanceof InkField).map(i => i!.inkData)).then((results) => { const wordResults = results.filter((r: any) => r.category === "inkWord"); console.log(wordResults); for (const word of wordResults) { const indices: number[] = word.strokeIds; - const r = Math.floor(Math.random() * 256); - const g = Math.floor(Math.random() * 256); - const b = Math.floor(Math.random() * 256); indices.forEach(i => { - inks[i].color = `rgb(${r}, ${g}, ${b})`; + if (wordToColor.has(word.recognizedText)) { + inks[i].color = wordToColor.get(word.recognizedText); + } }) } }); diff --git a/src/pen-gestures/GestureUtils.ts b/src/pen-gestures/GestureUtils.ts index 4e3493c1c..f14c573c3 100644 --- a/src/pen-gestures/GestureUtils.ts +++ b/src/pen-gestures/GestureUtils.ts @@ -35,6 +35,8 @@ export namespace GestureUtils { export enum Gestures { Box = "box", Line = "line", + StartBracket = "startbracket", + EndBracket = "endbracket", Stroke = "stroke", Scribble = "scribble", Text = "text" diff --git a/src/pen-gestures/ndollar.ts b/src/pen-gestures/ndollar.ts index 9e15ada2d..643d58591 100644 --- a/src/pen-gestures/ndollar.ts +++ b/src/pen-gestures/ndollar.ts @@ -142,7 +142,7 @@ export class Result { // // NDollarRecognizer constants // -const NumMultistrokes = 2; +const NumMultistrokes = 4; const NumPoints = 96; const SquareSize = 250.0; const OneDThreshold = 0.25; // customize to desired gesture set (usually 0.20 - 0.35) @@ -178,6 +178,15 @@ export class NDollarRecognizer { this.Multistrokes[1] = new Multistroke(GestureUtils.Gestures.Line, useBoundedRotationInvariance, new Array( new Array(new Point(12, 347), new Point(119, 347)) )); + this.Multistrokes[2] = new Multistroke(GestureUtils.Gestures.StartBracket, useBoundedRotationInvariance, new Array( + // new Array(new Point(145, 20), new Point(30, 21), new Point(34, 150)) + new Array(new Point(31, 25), new Point(145, 20), new Point(31, 25), new Point(34, 150)) + )); + this.Multistrokes[3] = new Multistroke(GestureUtils.Gestures.EndBracket, useBoundedRotationInvariance, new Array( + // new Array(new Point(150, 21), new Point(149, 150), new Point(26, 152)) + // new Array(new Point(150, 150), new Point(150, 0), new Point(150, 150), new Point(0, 150)) + new Array(new Point(10, 100), new Point(50, 12), new Point(100, 103)) + )); // // PREDEFINED STROKES -- cgit v1.2.3-70-g09d2 From dc6453e27375a1b3d614a74b7fd1d83695f130d7 Mon Sep 17 00:00:00 2001 From: Stanley Yip Date: Mon, 10 Feb 2020 20:02:43 -0500 Subject: some final stuff --- src/client/views/GestureOverlay.scss | 15 ++++++++++++++ src/client/views/GestureOverlay.tsx | 23 +++++++++++++--------- src/client/views/Palette.scss | 13 ++++++++++-- src/client/views/Palette.tsx | 1 + .../collectionFreeForm/CollectionFreeFormView.tsx | 9 ++++----- .../collections/collectionFreeForm/MarqueeView.tsx | 14 ++++++++++--- src/pen-gestures/ndollar.ts | 2 +- src/server/Search.ts | 2 +- 8 files changed, 58 insertions(+), 21 deletions(-) (limited to 'src/pen-gestures') diff --git a/src/client/views/GestureOverlay.scss b/src/client/views/GestureOverlay.scss index 7474ca839..107077792 100644 --- a/src/client/views/GestureOverlay.scss +++ b/src/client/views/GestureOverlay.scss @@ -5,6 +5,21 @@ top: 0; left: 0; touch-action: none; + + .pointerBubbles { + width: 100%; + height: 100%; + position: absolute; + pointer-events: none; + + .bubble { + position: absolute; + width: 15px; + height: 15px; + border-radius: 100%; + border: .5px solid grey; + } + } } .clipboardDoc-cont { diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index 4e9b87eea..5c4dd0c0a 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -32,8 +32,8 @@ import TouchScrollableMenu, { TouchScrollableMenuItem } from "./TouchScrollableM 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; @@ -394,9 +394,9 @@ export default class GestureOverlay extends Touchable { 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 > 0) { + 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) / 20)), this._possibilities.length - 1); + 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) { @@ -436,7 +436,7 @@ export default class GestureOverlay extends Touchable { let scriptWorked = false; if (NumCast(this._inkToTextDoc?.selectedIndex) > -1) { - const selectedButton = this._possibilities[NumCast(this._inkToTextDoc?.selectedIndex)]; + const selectedButton = this._possibilities[this._selectedIndex]; if (selectedButton) { selectedButton.props.onClick(); scriptWorked = true; @@ -507,8 +507,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 }); - actionPerformed = true; + if (this._d1.type !== "ink" && doc.type !== "ink") { + DocUtils.MakeLink({ doc: this._d1 }, { doc: doc }); + actionPerformed = true; + } } }; const ge = new CustomEvent("dashOnGesture", @@ -716,6 +718,9 @@ export default class GestureOverlay extends Touchable { }}>
+ {/*
+ {this._pointers.map(p =>
)} +
*/} ); } } @@ -743,8 +748,8 @@ 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) { diff --git a/src/client/views/Palette.scss b/src/client/views/Palette.scss index 4513de2b0..0ec879288 100644 --- a/src/client/views/Palette.scss +++ b/src/client/views/Palette.scss @@ -1,13 +1,14 @@ .palette-container { .palette-thumb { touch-action: pan-x; - overflow: scroll; position: absolute; - width: 90px; height: 70px; + overflow: hidden; .palette-thumbContent { transition: transform .3s; + width: max-content; + overflow: hidden; .collectionView { overflow: visible; @@ -17,5 +18,13 @@ } } } + + .palette-cover { + width: 50px; + height: 50px; + position: absolute; + bottom: 0; + border: 1px solid black; + } } } \ No newline at end of file diff --git a/src/client/views/Palette.tsx b/src/client/views/Palette.tsx index 10aac96a0..e04f814d1 100644 --- a/src/client/views/Palette.tsx +++ b/src/client/views/Palette.tsx @@ -72,6 +72,7 @@ export default class Palette extends React.Component { zoomToScale={emptyFunction} getScale={returnOne}> +
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 53fe2b18c..4b1bb09a9 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -457,7 +457,6 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { const inkFields = inks.map(i => Cast(i.data, InkField)); CognitiveServices.Inking.Appliers.InterpretStrokes(inkFields.filter(i => i instanceof InkField).map(i => i!.inkData)).then((results) => { const wordResults = results.filter((r: any) => r.category === "inkWord"); - console.log(wordResults); for (const word of wordResults) { const indices: number[] = word.strokeIds; indices.forEach(i => { @@ -467,13 +466,13 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { const uniqueColors: string[] = []; Array.from(this._wordPalette.values()).forEach(c => uniqueColors.indexOf(c) === -1 && uniqueColors.push(c)); inks[i].alternativeColors = new List(uniqueColors); - if (this._wordPalette.has(word.recognizedText)) { - inks[i].color = this._wordPalette.get(word.recognizedText); + if (this._wordPalette.has(word.recognizedText.toLowerCase())) { + inks[i].color = this._wordPalette.get(word.recognizedText.toLowerCase()); } else { for (const alt of word.alternates) { - if (this._wordPalette.has(alt.recognizedString)) { - inks[i].color = this._wordPalette.get(alt.recognizedString); + if (this._wordPalette.has(alt.recognizedString.toLowerCase())) { + inks[i].color = this._wordPalette.get(alt.recognizedString.toLowerCase()); break; } } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 19a71012a..8591144c0 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -375,7 +375,6 @@ export class MarqueeView extends React.Component FieldValue(sd.color) as string); const wordToColor = new Map(); - console.log(sets); sets.forEach((st: string, i: number) => { const words = st.split(","); words.forEach(word => { @@ -386,11 +385,20 @@ export class MarqueeView extends React.Component i instanceof InkField).map(i => i!.inkData)).then((results) => { const wordResults = results.filter((r: any) => r.category === "inkWord"); console.log(wordResults); + console.log(results); for (const word of wordResults) { const indices: number[] = word.strokeIds; indices.forEach(i => { - if (wordToColor.has(word.recognizedText)) { - inks[i].color = wordToColor.get(word.recognizedText); + if (wordToColor.has(word.recognizedText.toLowerCase())) { + inks[i].color = wordToColor.get(word.recognizedText.toLowerCase()); + } + else { + for (const alt of word.alternates) { + if (wordToColor.has(alt.recognizedString.toLowerCase())) { + inks[i].color = wordToColor.get(alt.recognizedString.toLowerCase()); + break; + } + } } }) } diff --git a/src/pen-gestures/ndollar.ts b/src/pen-gestures/ndollar.ts index 643d58591..365896197 100644 --- a/src/pen-gestures/ndollar.ts +++ b/src/pen-gestures/ndollar.ts @@ -185,7 +185,7 @@ export class NDollarRecognizer { this.Multistrokes[3] = new Multistroke(GestureUtils.Gestures.EndBracket, useBoundedRotationInvariance, new Array( // new Array(new Point(150, 21), new Point(149, 150), new Point(26, 152)) // new Array(new Point(150, 150), new Point(150, 0), new Point(150, 150), new Point(0, 150)) - new Array(new Point(10, 100), new Point(50, 12), new Point(100, 103)) + new Array(new Point(10, 100), new Point(50, 100), new Point(100, 12), new Point(150, 103), new Point(190, 100)) )); // diff --git a/src/server/Search.ts b/src/server/Search.ts index 43aa7e49c..21064e520 100644 --- a/src/server/Search.ts +++ b/src/server/Search.ts @@ -13,7 +13,7 @@ export namespace Search { }); return res; } catch (e) { - console.warn("Search error: " + e + document); + // console.warn("Search error: " + e + document); } } -- cgit v1.2.3-70-g09d2 From f689b3ae048941f23d67750ba488ca90bba578ee Mon Sep 17 00:00:00 2001 From: Stanley Yip Date: Tue, 11 Feb 2020 18:04:05 -0500 Subject: some more fixes --- src/client/util/InteractionUtils.tsx | 1 + .../collectionFreeForm/CollectionFreeFormView.tsx | 18 ++++++++++++++++-- .../collections/collectionFreeForm/MarqueeView.tsx | 1 + src/pen-gestures/ndollar.ts | 2 +- 4 files changed, 19 insertions(+), 3 deletions(-) (limited to 'src/pen-gestures') diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx index 8fc5e8098..184e37ba5 100644 --- a/src/client/util/InteractionUtils.tsx +++ b/src/client/util/InteractionUtils.tsx @@ -91,6 +91,7 @@ export namespace InteractionUtils { } export function IsType(e: PointerEvent | React.PointerEvent, type: string): boolean { + console.log(e.button); switch (type) { // pen and eraser are both pointer type 'pen', but pen is button 0 and eraser is button 5. -syip2 case PENTYPE: diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 4b1bb09a9..bb34f3d27 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -454,8 +454,22 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { } return false; }); - const inkFields = inks.map(i => Cast(i.data, InkField)); - CognitiveServices.Inking.Appliers.InterpretStrokes(inkFields.filter(i => i instanceof InkField).map(i => i!.inkData)).then((results) => { + // const inkFields = inks.map(i => Cast(i.data, InkField)); + const strokes: InkData[] = []; + inks.forEach(i => { + const d = Cast(i.data, InkField); + const x = NumCast(i.x); + const y = NumCast(i.y); + const left = Math.min(...d?.inkData.map(pd => pd.X) ?? [0]); + const top = Math.min(...d?.inkData.map(pd => pd.Y) ?? [0]); + if (d) { + strokes.push(d.inkData.map(pd => ({ X: pd.X + x - left, Y: pd.Y + y - top }))); + } + }); + console.log(strokes) + + CognitiveServices.Inking.Appliers.InterpretStrokes(strokes).then((results) => { + console.log(results); const wordResults = results.filter((r: any) => r.category === "inkWord"); for (const word of wordResults) { const indices: number[] = word.strokeIds; diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 8591144c0..e82ca6bf2 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -21,6 +21,7 @@ import MarqueeOptionsMenu from "./MarqueeOptionsMenu"; import { SubCollectionViewProps } from "../CollectionSubView"; import { CognitiveServices } from "../../../cognitive_services/CognitiveServices"; import { RichTextField } from "../../../../new_fields/RichTextField"; +import { InteractionUtils } from "../../../util/InteractionUtils"; interface MarqueeViewProps { getContainerTransform: () => Transform; diff --git a/src/pen-gestures/ndollar.ts b/src/pen-gestures/ndollar.ts index 365896197..bb92f62e1 100644 --- a/src/pen-gestures/ndollar.ts +++ b/src/pen-gestures/ndollar.ts @@ -185,7 +185,7 @@ export class NDollarRecognizer { this.Multistrokes[3] = new Multistroke(GestureUtils.Gestures.EndBracket, useBoundedRotationInvariance, new Array( // new Array(new Point(150, 21), new Point(149, 150), new Point(26, 152)) // new Array(new Point(150, 150), new Point(150, 0), new Point(150, 150), new Point(0, 150)) - new Array(new Point(10, 100), new Point(50, 100), new Point(100, 12), new Point(150, 103), new Point(190, 100)) + new Array(new Point(10, 100), new Point(100, 100), new Point(150, 12), new Point(200, 103), new Point(300, 100)) )); // -- cgit v1.2.3-70-g09d2 From 24d8fde04b562d474bb96669903fc42add2f9d84 Mon Sep 17 00:00:00 2001 From: Stanley Yip Date: Fri, 10 Apr 2020 18:26:23 -0700 Subject: some comments --- src/client/util/InteractionUtils.tsx | 7 +++++-- src/pen-gestures/ndollar.ts | 3 +++ 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src/pen-gestures') diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx index f2d569cf3..7e41b3744 100644 --- a/src/client/util/InteractionUtils.tsx +++ b/src/client/util/InteractionUtils.tsx @@ -13,7 +13,6 @@ export namespace InteractionUtils { export class MultiTouchEvent { constructor( readonly fingers: number, - // readonly points: T extends React.TouchEvent ? React.TouchList : TouchList, readonly targetTouches: T extends React.TouchEvent ? React.Touch[] : Touch[], readonly touches: T extends React.TouchEvent ? React.Touch[] : Touch[], readonly changedTouches: T extends React.TouchEvent ? React.Touch[] : Touch[], @@ -48,6 +47,11 @@ export namespace InteractionUtils { }; } + /** + * Turns an element onto a target for custom touch handling. + * @param element - element to add events to + * @param func - function to add to the event + */ export function MakeHoldTouchTarget( element: HTMLElement, func: (e: Event, me: MultiTouchEvent) => void @@ -78,7 +82,6 @@ export namespace InteractionUtils { return myTouches; } - // TODO: find a way to reference this function from InkingStroke instead of copy pastign here. copied bc of weird error when on mobile view export function CreatePolyline(points: { X: number, Y: number }[], left: number, top: number, color: string, width: number) { const pts = points.reduce((acc: string, pt: { X: number, Y: number }) => acc + `${pt.X - left},${pt.Y - top} `, ""); return ( diff --git a/src/pen-gestures/ndollar.ts b/src/pen-gestures/ndollar.ts index bb92f62e1..e5740d105 100644 --- a/src/pen-gestures/ndollar.ts +++ b/src/pen-gestures/ndollar.ts @@ -161,6 +161,9 @@ const AngleSimilarityThreshold = Deg2Rad(30.0); export class NDollarRecognizer { public Multistrokes: Multistroke[]; + /** + * @IMPORTANT - IF YOU'RE ADDING A NEW GESTURE, BE SURE TO INCREMENT THE NumMultiStrokes CONST RIGHT ABOVE THIS CLASS. + */ constructor(useBoundedRotationInvariance: boolean) // constructor { // -- cgit v1.2.3-70-g09d2 From af7fb7bf59ae3a2984d2ea8d668757f75d66d63d Mon Sep 17 00:00:00 2001 From: Stanley Yip Date: Fri, 10 Apr 2020 18:52:56 -0700 Subject: more comments --- src/client/util/InteractionUtils.tsx | 17 ++- src/client/views/GestureOverlay.tsx | 194 +++++++++++++++++++---------------- src/client/views/Touchable.tsx | 7 +- src/pen-gestures/GestureUtils.ts | 8 -- 4 files changed, 125 insertions(+), 101 deletions(-) (limited to 'src/pen-gestures') diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx index 7e41b3744..b1f136430 100644 --- a/src/client/util/InteractionUtils.tsx +++ b/src/client/util/InteractionUtils.tsx @@ -22,6 +22,11 @@ export namespace InteractionUtils { export interface MultiTouchEventDisposer { (): void; } + /** + * + * @param element - element to turn into a touch target + * @param startFunc - event handler, typically Touchable.onTouchStart (classes that inherit touchable can pass in this.onTouchStart) + */ export function MakeMultiTouchTarget( element: HTMLElement, startFunc: (e: Event, me: MultiTouchEvent) => void @@ -48,7 +53,7 @@ export namespace InteractionUtils { } /** - * Turns an element onto a target for custom touch handling. + * Turns an element onto a target for touch hold handling. * @param element - element to add events to * @param func - function to add to the event */ @@ -96,6 +101,11 @@ export namespace InteractionUtils { ); } + /** + * Returns whether or not the pointer event passed in is of the type passed in + * @param e - pointer event. this event could be from a mouse, a pen, or a finger + * @param type - InteractionUtils.(PENTYPE | ERASERTYPE | MOUSETYPE | TOUCHTYPE) + */ export function IsType(e: PointerEvent | React.PointerEvent, type: string): boolean { switch (type) { // pen and eraser are both pointer type 'pen', but pen is button 0 and eraser is button 5. -syip2 @@ -108,6 +118,11 @@ export namespace InteractionUtils { } } + /** + * Returns euclidean distance between two points + * @param pt1 + * @param pt2 + */ export function TwoPointEuclidist(pt1: React.Touch, pt2: React.Touch): number { return Math.sqrt(Math.pow(pt1.clientX - pt2.clientX, 2) + Math.pow(pt1.clientY - pt2.clientY, 2)); } diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index 69aa8dbaa..1977f2406 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -82,6 +82,9 @@ export default class GestureOverlay extends Touchable { this._inkToTextDoc = FieldValue(Cast(this._thumbDoc?.inkToTextDoc, Doc)); } + /** + * Ignores all touch events that belong to a hand being held down. + */ getNewTouches(e: React.TouchEvent | TouchEvent) { const ntt: (React.Touch | Touch)[] = Array.from(e.targetTouches); const nct: (React.Touch | Touch)[] = Array.from(e.changedTouches); @@ -121,6 +124,8 @@ export default class GestureOverlay extends Touchable { return; } + // this chunk adds new touch targets to a map of pointer events; this helps us keep track of individual fingers + // so that we can know, for example, if two fingers are pinching out or in. const actualPts: React.Touch[] = []; for (let i = 0; i < te.touches.length; i++) { const pt: any = te.touches.item(i); @@ -128,9 +133,6 @@ export default class GestureOverlay extends Touchable { // pen is also a touch, but with a radius of 0.5 (at least with the surface pens) // and this seems to be the only way of differentiating pen and touch on touch events if (pt.radiusX > 1 && pt.radiusY > 1) { - // if (typeof pt.identifier !== "string") { - // pt.identifier = Utils.GenerateGuid(); - // } this.prevPoints.set(pt.identifier, pt); } } @@ -144,6 +146,7 @@ export default class GestureOverlay extends Touchable { ptsToDelete.forEach(pt => this.prevPoints.delete(pt)); const nts = this.getNewTouches(te); + // if there are fewer than five touch events, handle as a touch event if (nts.nt.length < 5) { const target = document.elementFromPoint(te.changedTouches.item(0).clientX, te.changedTouches.item(0).clientY); target?.dispatchEvent( @@ -161,7 +164,7 @@ export default class GestureOverlay extends Touchable { ) ); if (nts.nt.length === 1) { - console.log("started"); + // -- radial menu code -- this._holdTimer = setTimeout(() => { console.log("hold"); const target = document.elementFromPoint(te.changedTouches.item(0).clientX, te.changedTouches.item(0).clientY); @@ -200,6 +203,7 @@ export default class GestureOverlay extends Touchable { document.addEventListener("touchmove", this.onReactTouchMove); document.addEventListener("touchend", this.onReactTouchEnd); } + // otherwise, handle as a hand event else { this.handleHandDown(te); document.removeEventListener("touchmove", this.onReactTouchMove); @@ -207,67 +211,6 @@ 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>("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>("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); @@ -306,6 +249,8 @@ export default class GestureOverlay extends Touchable { } }) ); + + // cleanup any lingering pointers for (let i = 0; i < e.changedTouches.length; i++) { const pt = e.changedTouches.item(i); if (pt) { @@ -324,6 +269,10 @@ export default class GestureOverlay extends Touchable { handleHandDown = async (e: React.TouchEvent) => { this._holdTimer && clearTimeout(this._holdTimer); + + // this chunk of code helps us keep track of which touch events are associated with a hand event + // so that if a hand is held down, but a second hand is interacting with dash, the second hand's events + // won't interfere with the first hand's events. const fingers = new Array(); for (let i = 0; i < e.touches.length; i++) { const pt: any = e.touches.item(i); @@ -338,6 +287,8 @@ export default class GestureOverlay extends Touchable { } } } + + // this chunk of code determines whether this is a left hand or a right hand, as well as which pointer is the thumb and pointer const thumb = fingers.reduce((a, v) => a.clientY > v.clientY ? a : v, fingers[0]); const rightMost = Math.max(...fingers.map(f => f.clientX)); const leftMost = Math.min(...fingers.map(f => f.clientX)); @@ -354,6 +305,7 @@ export default class GestureOverlay extends Touchable { console.log("not hand"); } this.pointerIdentifier = pointer?.identifier; + runInAction(() => { this._pointerY = pointer?.clientY; if (thumb.identifier === this.thumbIdentifier) { @@ -370,6 +322,7 @@ export default class GestureOverlay extends Touchable { const minX = Math.min(...others.map(f => f.clientX)); const minY = Math.min(...others.map(f => f.clientY)); + // load up the palette collection around the thumb const thumbDoc = await Cast(CurrentUserUtils.setupThumbDoc(CurrentUserUtils.UserDocument), Doc); if (thumbDoc) { runInAction(() => { @@ -393,6 +346,7 @@ export default class GestureOverlay extends Touchable { @action handleHandMove = (e: TouchEvent) => { + // update pointer trackers const fingers = new Array(); for (let i = 0; i < e.touches.length; i++) { const pt: any = e.touches.item(i); @@ -411,15 +365,19 @@ export default class GestureOverlay extends Touchable { } } } + // update hand trackers const thumb = fingers.reduce((a, v) => a.clientY > v.clientY ? a : v, fingers[0]); if (thumb?.identifier && thumb?.identifier === this.thumbIdentifier) { this._hands.set(thumb.identifier, fingers); } + // loop through every changed pointer for (let i = 0; i < e.changedTouches.length; i++) { const pt = e.changedTouches.item(i); + // if the thumb was moved if (pt && pt.identifier === this.thumbIdentifier && this._thumbY) { if (this._thumbX && this._thumbY) { + // moving a thumb horiz. changes the palette collection selection, moving vert. changes the selection of any menus on the current palette item 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)) { @@ -433,19 +391,8 @@ export default class GestureOverlay extends Touchable { } } } - - // 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 the pointer finger was moved if (pt && pt.identifier === this.pointerIdentifier) { this._pointerY = pt.clientY; } @@ -454,27 +401,31 @@ export default class GestureOverlay extends Touchable { @action handleHandUp = (e: TouchEvent) => { + // sometimes, users may lift up their thumb or index finger if they can't stretch far enough to scroll an entire menu, + // so we don't want to just remove the palette when that happens if (e.touches.length < 3) { - // this.onTouchEnd(e); if (this.thumbIdentifier) this._hands.delete(this.thumbIdentifier); this._palette = undefined; this.thumbIdentifier = undefined; this._thumbDoc = undefined; + // this chunk of code is for handling the ink to text toolglass let scriptWorked = false; if (NumCast(this._inkToTextDoc?.selectedIndex) > -1) { + // if there is a text option selected, activate it const selectedButton = this._possibilities[this._selectedIndex]; if (selectedButton) { selectedButton.props.onClick(); scriptWorked = true; } } - + // if there isn't a text option selected, dry the ink strokes into ink documents if (!scriptWorked) { this._strokes.forEach(s => { this.dispatchGesture(GestureUtils.Gestures.Stroke, s); }); } + this._strokes = []; this._points = []; this._possibilities = []; @@ -482,6 +433,72 @@ export default class GestureOverlay extends Touchable { } } + /** + * Code for radial menu + */ + 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>("dashOnTouchHoldMove", + { + bubbles: true, + detail: { + fingers: this.prevPoints.size, + targetTouches: nts.ntt, + touches: nts.nt, + changedTouches: nts.nct, + touchEvent: e + } + }) + ); + } + + /** + * Code for radial menu + */ + 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>("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(); + } + @action onPointerDown = (e: React.PointerEvent) => { if (InteractionUtils.IsType(e, InteractionUtils.PENTYPE) || (InkingControl.Instance.selectedTool === InkTool.Highlighter || InkingControl.Instance.selectedTool === InkTool.Pen)) { @@ -524,22 +541,28 @@ export default class GestureOverlay extends Touchable { handleLineGesture = (): boolean => { let actionPerformed = false; const B = this.svgBounds; + + // get the two targets at the ends of the line const ep1 = this._points[0]; const ep2 = this._points[this._points.length - 1]; - const target1 = document.elementFromPoint(ep1.X, ep1.Y); const target2 = document.elementFromPoint(ep2.X, ep2.Y); + + // callback function to be called by each target const callback = (doc: Doc) => { if (!this._d1) { this._d1 = doc; } + // we don't want to create a link of both endpoints are the same document (doing so makes drawing an l very hard) else if (this._d1 !== doc && !LinkManager.Instance.doesLinkExist(this._d1, doc)) { + // we don't want to create a link between ink strokes (doing so makes drawing a t very hard) if (this._d1.type !== "ink" && doc.type !== "ink") { DocUtils.MakeLink({ doc: this._d1 }, { doc: doc }, "gestural link"); actionPerformed = true; } } }; + const ge = new CustomEvent("dashOnGesture", { bubbles: true, @@ -575,6 +598,7 @@ export default class GestureOverlay extends Touchable { 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 a toolglass is selected and the stroke starts within the toolglass boundaries if (this.Tool !== ToolglassTools.None && xInGlass && yInGlass) { switch (this.Tool) { case ToolglassTools.InkToText: @@ -583,20 +607,19 @@ export default class GestureOverlay extends Touchable { 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)); + + // if we receive any word results from cognitive services, display them runInAction(() => { this._possibilities = possibilities.map(p => GestureOverlay.Instance.dispatchGesture(GestureUtils.Gestures.Text, [{ X: l, Y: t }], p)} />); @@ -609,6 +632,7 @@ export default class GestureOverlay extends Touchable { break; } } + // if we're not drawing in a toolglass try to recognize as gesture else { const result = GestureUtils.GestureRecognizer.Recognize(new Array(points)); let actionPerformed = false; @@ -638,6 +662,7 @@ export default class GestureOverlay extends Touchable { } } + // if no gesture (or if the gesture was unsuccessful), "dry" the stroke into an ink document if (!actionPerformed) { this.dispatchGesture(GestureUtils.Gestures.Stroke); this._points = []; @@ -762,9 +787,6 @@ export default class GestureOverlay extends Touchable { }}> - {/*
- {this._pointers.map(p =>
)} -
*/} ); } } diff --git a/src/client/views/Touchable.tsx b/src/client/views/Touchable.tsx index 08310786b..10d023d83 100644 --- a/src/client/views/Touchable.tsx +++ b/src/client/views/Touchable.tsx @@ -64,20 +64,15 @@ export abstract class Touchable extends React.Component { case 1: this.handle1PointerDown(te, me); te.persist(); + // -- code for radial menu -- // if (this.holdTimer) { // clearTimeout(this.holdTimer) // this.holdTimer = undefined; // } - // console.log(this.holdTimer); - // console.log(this.holdTimer); break; case 2: this.handle2PointersDown(te, me); - // e.stopPropagation(); break; - // case 5: - // this.handleHandDown(te); - // break; } } } diff --git a/src/pen-gestures/GestureUtils.ts b/src/pen-gestures/GestureUtils.ts index f14c573c3..b8a82ab4d 100644 --- a/src/pen-gestures/GestureUtils.ts +++ b/src/pen-gestures/GestureUtils.ts @@ -43,12 +43,4 @@ export namespace GestureUtils { } export const GestureRecognizer = new NDollarRecognizer(false); - - export function GestureOptions(name: string, gestureData?: any): (params: {}) => any { - switch (name) { - case Gestures.Box: - break; - } - throw new Error("This means that you're trying to do something with the gesture that hasn't been defined yet. Define it in GestureUtils.ts"); - } } \ No newline at end of file -- cgit v1.2.3-70-g09d2