diff options
Diffstat (limited to 'src/client')
| -rw-r--r-- | src/client/util/CurrentUserUtils.ts | 8 | ||||
| -rw-r--r-- | src/client/util/InteractionUtils.tsx | 26 | ||||
| -rw-r--r-- | src/client/util/SettingsManager.tsx | 4 | ||||
| -rw-r--r-- | src/client/views/GestureOverlay.tsx | 49 | ||||
| -rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 6 | ||||
| -rw-r--r-- | src/client/views/nodes/button/FontIconBox.tsx | 9 |
6 files changed, 50 insertions, 52 deletions
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 1c9f89fa0..bfa868dbc 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -12,6 +12,7 @@ import { ComputedField, ScriptField } from "../../fields/ScriptField"; import { Cast, DateCast, DocCast, PromiseValue, StrCast } from "../../fields/Types"; import { nullAudio } from "../../fields/URLField"; import { SetCachedGroups, SharingPermissions } from "../../fields/util"; +import { GestureUtils } from "../../pen-gestures/GestureUtils"; import { OmitKeys, Utils } from "../../Utils"; import { DocServer } from "../DocServer"; import { Docs, DocumentOptions, DocUtils, FInfo } from "../documents/Documents"; @@ -631,9 +632,9 @@ export class CurrentUserUtils { { title: "Write", toolTip: "Write (Ctrl+Shift+P)", btnType: ButtonType.ToggleButton, icon: "pen", scripts: {onClick:'{ return setActiveTool("write", _readOnly_);}'} }, { title: "Eraser", toolTip: "Eraser (Ctrl+E)", btnType: ButtonType.ToggleButton, icon: "eraser", scripts: {onClick:'{ return setActiveTool("eraser", _readOnly_);}' }}, // { title: "Highlighter", toolTip: "Highlighter (Ctrl+H)", btnType: ButtonType.ToggleButton, icon: "highlighter", scripts:{onClick: 'setActiveTool("highlighter")'} }, - { title: "Circle", toolTip: "Circle (Ctrl+Shift+C)", btnType: ButtonType.ToggleButton, icon: "circle", scripts: {onClick:'{ return setActiveTool("circle", _readOnly_);}'} }, - // { title: "Square", toolTip: "Square (Ctrl+Shift+S)", btnType: ButtonType.ToggleButton, icon: "square", click: 'setActiveTool("square")' }, - { title: "Line", toolTip: "Line (Ctrl+Shift+L)", btnType: ButtonType.ToggleButton, icon: "minus", scripts: {onClick:'{ return setActiveTool("line", _readOnly_);}' }}, + { title: "Circle", toolTip: "Circle (Ctrl+Shift+C)", btnType: ButtonType.ToggleButton, icon: "circle", scripts: {onClick:`{ return setActiveTool("${GestureUtils.Gestures.Circle}", _readOnly_);}`} }, + { title: "Square", toolTip: "Square (Ctrl+Shift+S)", btnType: ButtonType.ToggleButton, icon: "square", scripts: {onClick:`{ return setActiveTool("${GestureUtils.Gestures.Rectangle}", _readOnly_);}`} }, + { title: "Line", toolTip: "Line (Ctrl+Shift+L)", btnType: ButtonType.ToggleButton, icon: "minus", scripts: {onClick:`{ return setActiveTool("${GestureUtils.Gestures.Line}", _readOnly_);}`} }, { title: "Mask", toolTip: "Mask", btnType: ButtonType.ToggleButton, icon: "user-circle", scripts: {onClick:'{ return setIsInkMask(_readOnly_);}'} }, { title: "Fill", toolTip: "Fill color", btnType: ButtonType.ColorButton, icon: "fill-drip",ignoreClick: true, scripts: {script: '{ return setFillColor(value, _readOnly_);}'} }, { title: "Width", toolTip: "Stroke width", btnType: ButtonType.NumberButton, ignoreClick: true, scripts: {script: '{ return setStrokeWidth(value, _readOnly_);}'}, numBtnType: NumButtonType.Slider, numBtnMin: 1}, @@ -797,6 +798,7 @@ export class CurrentUserUtils { doc._raiseWhenDragged ?? (doc._raiseWhenDragged = true); doc._showLabel ?? (doc._showLabel = true); doc.textAlign ?? (doc.textAlign = "left"); + doc.activeTool = InkTool.None; doc.activeInkColor ?? (doc.activeInkColor = "rgb(0, 0, 0)");; doc.activeInkWidth ?? (doc.activeInkWidth = 1); doc.activeInkBezier ?? (doc.activeInkBezier = "0"); diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx index 85700da37..6622b498d 100644 --- a/src/client/util/InteractionUtils.tsx +++ b/src/client/util/InteractionUtils.tsx @@ -1,4 +1,5 @@ import React = require('react'); +import { GestureUtils } from '../../pen-gestures/GestureUtils'; import { Utils } from '../../Utils'; import './InteractionUtils.scss'; @@ -186,7 +187,7 @@ export namespace InteractionUtils { export function makePolygon(shape: string, points: { X: number; Y: number }[]) { if (points.length > 1 && points[points.length - 1].X === points[0].X && points[points.length - 1].Y + 1 === points[0].Y) { //pointer is up (first and last points are the same) - if (shape === 'arrow' || shape === 'line' || shape === 'circle') { + if (shape === GestureUtils.Gestures.Arrow || shape === GestureUtils.Gestures.Line || shape === GestureUtils.Gestures.Circle) { //if arrow or line, the two end points should be the starting and the ending point var left = points[0].X; var top = points[0].Y; @@ -208,7 +209,7 @@ export namespace InteractionUtils { left = points[0].X; bottom = points[points.length - 1].Y; top = points[0].Y; - if (shape !== 'arrow' && shape !== 'line' && shape !== 'circle') { + if (shape !== GestureUtils.Gestures.Arrow && shape !== GestureUtils.Gestures.Line && shape !== GestureUtils.Gestures.Circle) { //switch left/right and top/bottom if needed if (left > right) { const temp = right; @@ -224,20 +225,20 @@ export namespace InteractionUtils { } points = []; switch (shape) { - case 'rectangle': + case GestureUtils.Gestures.Rectangle: points.push({ X: left, Y: top }); points.push({ X: right, Y: top }); points.push({ X: right, Y: bottom }); points.push({ X: left, Y: bottom }); points.push({ X: left, Y: top }); break; - case 'triangle': + case GestureUtils.Gestures.Triangle: points.push({ X: left, Y: bottom }); points.push({ X: right, Y: bottom }); points.push({ X: (right + left) / 2, Y: top }); points.push({ X: left, Y: bottom }); break; - case 'circle': + case GestureUtils.Gestures.Circle: const centerX = (Math.max(left, right) + Math.min(left, right)) / 2; const centerY = (Math.max(top, bottom) + Math.min(top, bottom)) / 2; const radius = Math.max(centerX - Math.min(left, right), centerY - Math.min(top, bottom)); @@ -253,7 +254,7 @@ export namespace InteractionUtils { points.push({ X: Math.min(left, right), Y: Math.sqrt(Math.pow(radius, 2) - Math.pow(Math.min(left, right) - centerX, 2)) + centerY }); break; - case 'line': + case GestureUtils.Gestures.Line: points.push({ X: left, Y: top }); points.push({ X: right, Y: bottom }); break; @@ -266,17 +267,14 @@ export namespace InteractionUtils { * @param type - InteractionUtils.(PENTYPE | ERASERTYPE | MOUSETYPE | TOUCHTYPE) */ export function IsType(e: PointerEvent | React.PointerEvent, type: string): boolean { + // prettier-ignore switch (type) { // pen and eraser are both pointer type 'pen', but pen is button 0 and eraser is button 5. -syip2 - case PENTYPE: - return e.pointerType === PENTYPE && (e.button === -1 || e.button === 0); - case ERASERTYPE: - return e.pointerType === PENTYPE && e.button === (e instanceof PointerEvent ? ERASER_BUTTON : ERASER_BUTTON); - case TOUCHTYPE: - return e.pointerType === TOUCHTYPE; - default: - return e.pointerType === type; + case PENTYPE: return e.pointerType === PENTYPE && (e.button === -1 || e.button === 0); + case ERASERTYPE: return e.pointerType === PENTYPE && e.button === (e instanceof PointerEvent ? ERASER_BUTTON : ERASER_BUTTON); + case TOUCHTYPE: return e.pointerType === TOUCHTYPE; } + return e.pointerType === type; } /** diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx index a185c8936..92032a8f9 100644 --- a/src/client/util/SettingsManager.tsx +++ b/src/client/util/SettingsManager.tsx @@ -186,6 +186,10 @@ export class SettingsManager extends React.Component<{}> { <input type="checkbox" onChange={e => FontIconBox.SetShowLabels(!FontIconBox.GetShowLabels())} checked={FontIconBox.GetShowLabels()} /> <div className="preferences-check">Show button labels</div> </div> + <div> + <input type="checkbox" onChange={e => FontIconBox.SetRecognizeGesturs(!FontIconBox.GetRecognizeGestures())} checked={FontIconBox.GetRecognizeGestures()} /> + <div className="preferences-check">Recognize ink Gesturs</div> + </div> </div> ); } diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index 850688e7e..23b03bc50 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -684,7 +684,7 @@ export class GestureOverlay extends Touchable<GestureOverlayProps> { } //if any of the shape is activated in the CollectionFreeFormViewChrome else if (this.InkShape) { - this.makePolygon(this.InkShape, false); + this.makeBezierPolygon(this.InkShape, false); this.dispatchGesture(GestureUtils.Gestures.Stroke); this._points.length = 0; if (!CollectionFreeFormViewChrome.Instance?._keepPrimitiveMode) { @@ -699,27 +699,17 @@ export class GestureOverlay extends Touchable<GestureOverlayProps> { let actionPerformed = false; if (Doc.UserDoc().recognizeGestures && result && result.Score > 0.7) { switch (result.Name) { - case GestureUtils.Gestures.Box: - actionPerformed = this.dispatchGesture(GestureUtils.Gestures.Box); - break; + case GestureUtils.Gestures.Triangle: + case GestureUtils.Gestures.Rectangle: + case GestureUtils.Gestures.Circle: + this.makeBezierPolygon(result.Name, true); case GestureUtils.Gestures.StartBracket: - actionPerformed = this.dispatchGesture(GestureUtils.Gestures.StartBracket); - break; case GestureUtils.Gestures.EndBracket: - actionPerformed = this.dispatchGesture('endbracket'); + actionPerformed = this.dispatchGesture(result.Name); break; case GestureUtils.Gestures.Line: actionPerformed = this.handleLineGesture(); break; - case GestureUtils.Gestures.Triangle: - actionPerformed = this.makePolygon('triangle', true); - break; - case GestureUtils.Gestures.Circle: - actionPerformed = this.makePolygon('circle', true); - break; - case GestureUtils.Gestures.Rectangle: - actionPerformed = this.makePolygon('rectangle', true); - break; case GestureUtils.Gestures.Scribble: console.log('scribble'); break; @@ -760,11 +750,7 @@ export class GestureOverlay extends Touchable<GestureOverlayProps> { CollectionFreeFormViewChrome.Instance?.primCreated(); }; - makePolygon = (shape: string, gesture: boolean) => { - //take off gesture recognition for now - if (gesture) { - return false; - } + makeBezierPolygon = (shape: string, gesture: boolean) => { const xs = this._points.map(p => p.X); const ys = this._points.map(p => p.Y); var right = Math.max(...xs); @@ -794,7 +780,7 @@ export class GestureOverlay extends Touchable<GestureOverlayProps> { left = this._points[0].X; bottom = this._points[this._points.length - 2].Y; top = this._points[0].Y; - if (shape !== 'arrow' && shape !== 'line' && shape !== 'circle') { + if (shape !== GestureUtils.Gestures.Arrow && shape !== GestureUtils.Gestures.Line && shape !== GestureUtils.Gestures.Circle) { if (left > right) { const temp = right; right = left; @@ -809,9 +795,7 @@ export class GestureOverlay extends Touchable<GestureOverlayProps> { } this._points.length = 0; switch (shape) { - //must push an extra point in the end so InteractionUtils knows pointer is up. - //must be (points[0].X,points[0]-1) - case 'rectangle': + case GestureUtils.Gestures.Rectangle: this._points.push({ X: left, Y: top }); this._points.push({ X: left, Y: top }); this._points.push({ X: right, Y: top }); @@ -834,7 +818,7 @@ export class GestureOverlay extends Touchable<GestureOverlayProps> { break; - case 'triangle': + case GestureUtils.Gestures.Triangle: this._points.push({ X: left, Y: bottom }); this._points.push({ X: left, Y: bottom }); @@ -852,7 +836,7 @@ export class GestureOverlay extends Touchable<GestureOverlayProps> { this._points.push({ X: left, Y: bottom }); break; - case 'circle': + case GestureUtils.Gestures.Circle: // Approximation of a circle using 4 Bézier curves in which the constant "c" reduces the maximum radial drift to 0.019608%, // making the curves indistinguishable from a circle. // Source: https://spencermortensen.com/articles/bezier-circle/ @@ -884,7 +868,7 @@ export class GestureOverlay extends Touchable<GestureOverlayProps> { break; - case 'line': + case GestureUtils.Gestures.Line: if (Math.abs(firstx - lastx) < 10 && Math.abs(firsty - lasty) > 10) { lastx = firstx; } @@ -897,7 +881,7 @@ export class GestureOverlay extends Touchable<GestureOverlayProps> { this._points.push({ X: lastx, Y: lasty }); this._points.push({ X: lastx, Y: lasty }); break; - case 'arrow': + case GestureUtils.Gestures.Arrow: const x1 = left; const y1 = top; const x2 = right; @@ -914,12 +898,11 @@ export class GestureOverlay extends Touchable<GestureOverlayProps> { this._points.push({ X: x3, Y: y3 }); this._points.push({ X: x4, Y: y4 }); this._points.push({ X: x2, Y: y2 }); - // this._points.push({ X: x1, Y: y1 - 1 }); } - return true; + return false; }; - dispatchGesture = (gesture: 'box' | 'line' | 'startbracket' | 'endbracket' | 'stroke' | 'scribble' | 'text', stroke?: InkData, data?: any) => { + dispatchGesture = (gesture: GestureUtils.Gestures, stroke?: InkData, data?: any) => { const target = document.elementFromPoint((stroke ?? this._points)[0].X, (stroke ?? this._points)[0].Y); return ( target?.dispatchEvent( @@ -1136,7 +1119,7 @@ ScriptingGlobals.add(function resetPen() { }, 'resets the pen tool'); ScriptingGlobals.add( function createText(text: any, x: any, y: any) { - GestureOverlay.Instance.dispatchGesture('text', [{ X: x, Y: y }], text); + GestureOverlay.Instance.dispatchGesture(GestureUtils.Gestures.Text, [{ X: x, Y: y }], text); }, 'creates a text document with inputted text and coordinates', '(text: any, x: any, y: any)' diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 5d4e1c999..daf69d4f6 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -568,6 +568,10 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection @undoBatch onGesture = (e: Event, ge: GestureUtils.GestureEvent) => { switch (ge.gesture) { + default: + case GestureUtils.Gestures.Circle: + case GestureUtils.Gestures.Rectangle: + case GestureUtils.Gestures.Triangle: case GestureUtils.Gestures.Stroke: const points = ge.points; const B = this.getTransform().transformBounds(ge.bounds.left, ge.bounds.top, ge.bounds.width, ge.bounds.height); @@ -597,7 +601,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection this.addDocument(inkDoc); e.stopPropagation(); break; - case GestureUtils.Gestures.Box: + case GestureUtils.Gestures.Rectangle: const lt = this.getTransform().transformPoint(Math.min(...ge.points.map(p => p.X)), Math.min(...ge.points.map(p => p.Y))); const rb = this.getTransform().transformPoint(Math.max(...ge.points.map(p => p.X)), Math.max(...ge.points.map(p => p.Y))); const bounds = { x: lt[0], r: rb[0], y: lt[1], b: rb[1] }; diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx index 6d1751b25..6eaf3c31a 100644 --- a/src/client/views/nodes/button/FontIconBox.tsx +++ b/src/client/views/nodes/button/FontIconBox.tsx @@ -11,6 +11,7 @@ import { InkTool } from '../../../../fields/InkField'; import { ScriptField } from '../../../../fields/ScriptField'; import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; import { WebField } from '../../../../fields/URLField'; +import { GestureUtils } from '../../../../pen-gestures/GestureUtils'; import { aggregateBounds, Utils } from '../../../../Utils'; import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; @@ -85,6 +86,12 @@ export class FontIconBox extends DocComponent<ButtonProps>() { static SetShowLabels(show: boolean) { Doc.UserDoc()._showLabel = show; } + static GetRecognizeGestures() { + return BoolCast(Doc.UserDoc()._recognizeGestures); + } + static SetRecognizeGesturs(show: boolean) { + Doc.UserDoc()._recognizeGestures = show; + } // Determining UI Specs @computed get label() { @@ -775,7 +782,7 @@ ScriptingGlobals.add(function setActiveTool(tool: string, checkResult?: boolean) if (checkResult) { return (Doc.ActiveTool === tool && !GestureOverlay.Instance?.InkShape) || GestureOverlay.Instance?.InkShape === tool ? Colors.MEDIUM_BLUE : 'transparent'; } - if (['circle', 'square', 'line'].includes(tool)) { + if ([GestureUtils.Gestures.Circle, GestureUtils.Gestures.Rectangle, GestureUtils.Gestures.Line, GestureUtils.Gestures.Triangle].includes(tool as any)) { if (GestureOverlay.Instance.InkShape === tool) { Doc.ActiveTool = InkTool.None; GestureOverlay.Instance.InkShape = InkTool.None; |
