From 4823e1c7ceb0e58cdb515e2bb013632d81767ae3 Mon Sep 17 00:00:00 2001 From: Naafiyan Ahmed Date: Tue, 5 Apr 2022 20:03:36 -0400 Subject: added basic grouping when exiting pen mode --- src/Utils.ts | 1 + src/client/util/CurrentUserUtils.ts | 1 + src/client/views/GestureOverlay.tsx | 23 +++--- .../collectionFreeForm/CollectionFreeFormView.tsx | 67 +++++++++++++++-- .../collections/collectionFreeForm/MarqueeView.tsx | 3 + src/client/views/nodes/button/FontIconBox.tsx | 83 +++++++++++++++++++++- 6 files changed, 161 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/Utils.ts b/src/Utils.ts index d0d891f77..6519b5d13 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -407,6 +407,7 @@ export function formatTime(time: number) { return (hours ? hours.toString() + ":" : "") + minutes.toString().padStart(2, '0') + ':' + seconds.toString().padStart(2, '0'); } +// x is furthest left, y is furthest top, r is furthest right, b is furthest bottom export function aggregateBounds(boundsList: { x: number, y: number, width?: number, height?: number }[], xpad: number, ypad: number) { const bounds = boundsList.map(b => ({ x: b.x, y: b.y, r: b.x + (b.width || 0), b: b.y + (b.height || 0) })).reduce((bounds, b) => ({ x: Math.min(b.x, bounds.x), y: Math.min(b.y, bounds.y), diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index c7f293f2c..6cab8c100 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1011,6 +1011,7 @@ export class CurrentUserUtils { static inkTools(doc: Doc) { const tools: Button[] = [ { title: "Pen", toolTip: "Pen (Ctrl+P)", btnType: ButtonType.ToggleButton, icon: "pen", click: 'setActiveInkTool("pen", _readOnly_)' }, + { title: "Mode", toolTip: "Mode (Ctrl+P)", btnType: ButtonType.ToggleButton, icon: "pen", click: 'setActiveInkTool("write", _readOnly_)' }, { title: "Eraser", toolTip: "Eraser (Ctrl+E)", btnType: ButtonType.ToggleButton, icon: "eraser", click: 'setActiveInkTool("eraser", _readOnly_)' }, // { title: "Highlighter", toolTip: "Highlighter (Ctrl+H)", btnType: ButtonType.ToggleButton, icon: "highlighter", click: 'setActiveInkTool("highlighter")' }, { title: "Circle", toolTip: "Circle (Ctrl+Shift+C)", btnType: ButtonType.ToggleButton, icon: "circle", click: 'setActiveInkTool("circle", _readOnly_)' }, diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index 05e5b7d5f..87b006a93 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -617,22 +617,23 @@ export class GestureOverlay extends Touchable { newPoints.pop(); const controlPoints: { X: number, Y: number }[] = []; - // const bezierCurves = fitCurve(newPoints, 10); - // for (const curve of bezierCurves) { + const bezierCurves = fitCurve(newPoints, 10); + for (const curve of bezierCurves) { - // controlPoints.push({ X: curve[0][0], Y: curve[0][1] }); - // controlPoints.push({ X: curve[1][0], Y: curve[1][1] }); - // controlPoints.push({ X: curve[2][0], Y: curve[2][1] }); - // controlPoints.push({ X: curve[3][0], Y: curve[3][1] }); + controlPoints.push({ X: curve[0][0], Y: curve[0][1] }); + controlPoints.push({ X: curve[1][0], Y: curve[1][1] }); + controlPoints.push({ X: curve[2][0], Y: curve[2][1] }); + controlPoints.push({ X: curve[3][0], Y: curve[3][1] }); - // } - // const dist = Math.sqrt((controlPoints[0].X - controlPoints.lastElement().X) * (controlPoints[0].X - controlPoints.lastElement().X) + - // (controlPoints[0].Y - controlPoints.lastElement().Y) * (controlPoints[0].Y - controlPoints.lastElement().Y)); - // if (controlPoints.length > 4 && dist < 10) controlPoints[controlPoints.length - 1] = controlPoints[0]; - // this._points = controlPoints; + } + const dist = Math.sqrt((controlPoints[0].X - controlPoints.lastElement().X) * (controlPoints[0].X - controlPoints.lastElement().X) + + (controlPoints[0].Y - controlPoints.lastElement().Y) * (controlPoints[0].Y - controlPoints.lastElement().Y)); + if (controlPoints.length > 4 && dist < 10) controlPoints[controlPoints.length - 1] = controlPoints[0]; + this._points = controlPoints; this.dispatchGesture(GestureUtils.Gestures.Stroke); + } this._points = []; } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index e2ea81392..a694ca2b3 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -3,7 +3,7 @@ import { action, computed, IReactionDisposer, observable, reaction, runInAction import { observer } from "mobx-react"; import { computedFn } from "mobx-utils"; import { DateField } from "../../../../fields/DateField"; -import { Doc, HeightSym, Opt, StrListCast, WidthSym } from "../../../../fields/Doc"; +import { Doc, DocListCast, HeightSym, Opt, StrListCast, WidthSym } from "../../../../fields/Doc"; import { Id } from "../../../../fields/FieldSymbols"; import { InkData, InkField, InkTool, PointData, Segment } from "../../../../fields/InkField"; import { List } from "../../../../fields/List"; @@ -17,7 +17,7 @@ import { GestureUtils } from "../../../../pen-gestures/GestureUtils"; import { aggregateBounds, emptyFunction, intersectRect, returnFalse, setupMoveUpEvents, Utils } from "../../../../Utils"; import { CognitiveServices } from "../../../cognitive_services/CognitiveServices"; import { DocServer } from "../../../DocServer"; -import { Docs, DocUtils } from "../../../documents/Documents"; +import { Docs, DocumentOptions, DocUtils } from "../../../documents/Documents"; import { DocumentType } from "../../../documents/DocumentTypes"; import { CurrentUserUtils } from "../../../util/CurrentUserUtils"; import { DocumentManager } from "../../../util/DocumentManager"; @@ -97,6 +97,9 @@ export class CollectionFreeFormView extends CollectionSubView = new Map(); private _lastTap = 0; private _batch: UndoManager.Batch | undefined = undefined; + + // private isWritingMode: boolean = true; + // private writingModeDocs: Doc[] = []; private get isAnnotationOverlay() { return this.props.isAnnotationOverlay; } private get scaleFieldKey() { return this.props.scaleField || "_viewScale"; } @@ -114,6 +117,7 @@ export class CollectionFreeFormView extends CollectionSubView(); @observable _marqueeRef = React.createRef(); + @observable _marqueeViewRef = React.createRef(); @observable _keyframeEditing = false; @observable ChildDrag: DocumentView | undefined; // child document view being dragged. needed to update drop areas of groups when a group item is dragged. @@ -431,6 +435,26 @@ export class CollectionFreeFormView extends CollectionSubView { + if (!InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE)) { + document.removeEventListener("pointerup", this.onPenUp); + const currentCol = DocListCast(this.rootDoc.currentInkDoc) + const rootDocList = DocListCast(this.rootDoc.data); + console.log("rootDocList", rootDocList[rootDocList.length - 1]); + console.log("currentCol", currentCol); + // if (!currentCol[0].data) { + // currentCol[0].data = []; + // } + // let docList = DocListCast(currentCol[0]); + + currentCol.push(rootDocList[rootDocList.length - 1]); + console.log(currentCol); + + this._batch?.end(); + } + } + @action onPointerDown = (e: React.PointerEvent): void => { this._downX = this._lastX = e.pageX; @@ -442,7 +466,32 @@ export class CollectionFreeFormView extends CollectionSubView(); @undoBatch onGesture = (e: Event, ge: GestureUtils.GestureEvent) => { switch (ge.gesture) { @@ -494,7 +545,14 @@ export class CollectionFreeFormView extends CollectionSubView 0 ? undefined : this.nudge} addDocTab={this.addDocTab} diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index b10b0912f..eeb2b653b 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -60,7 +60,9 @@ export class MarqueeView extends React.Component { + const selected = ffView.unprocessedDocs; + ffView._marqueeViewRef.current?.getCollection(ffView.unprocessedDocs, undefined, [], true); + // loop through selected an get the bound + const bounds: { x: number, y: number, width?: number, height?: number }[] = [] + + selected.map(action(d => { + const x = NumCast(d.x); + const y = NumCast(d.y); + const width = d[WidthSym](); + const height = d[HeightSym](); + bounds.push({x, y, width, height}); + })) + + const aggregBounds = aggregateBounds(bounds, 0, 0); + const marqViewRef = ffView._marqueeViewRef.current; + + // set the vals for bounds in marqueeView + if (marqViewRef) { + marqViewRef._downX = aggregBounds.x; + marqViewRef._downY = aggregBounds.y; + marqViewRef._lastX = aggregBounds.r; + marqViewRef._lastY = aggregBounds.b; + } + + selected.map(action(d => { + const dx = NumCast(d.x); + const dy = NumCast(d.y); + delete d.x; + delete d.y; + delete d.activeFrame; + delete d._timecodeToShow; // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection + delete d._timecodeToHide; // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection + // TODO: nda - actually calc the bounds + // get the bounds + // d.x = dx - aggregBounds.x; + // d.y = dy - aggregBounds.y; + + // d.x = dx - aggregBounds.x ; + // d.y = dy; + if (marqViewRef?.Bounds) { + d.x = dx - marqViewRef.Bounds.left - marqViewRef.Bounds?.width / 2; + d.y = dy - marqViewRef.Bounds.top - marqViewRef.Bounds.height / 2; + } + console.log(d[DataSym], d.x, d.y) + return d; + })); + ffView.props.removeDocument?.(selected); + // TODO: nda - this is the code to actually get a new grouped collection + // const newCollection = ffView._marqueeViewRef.current?.getCollection(ffView.unprocessedDocs, undefined, [], true); + const newCollection = marqViewRef?.getCollection(selected, undefined, [], true); + console.log("newcoll:", newCollection?.[DataSym]); + + // nda - bug: when deleting a stroke before leaving writing mode, delete the stroke from unprocessed ink docs + newCollection && ffView.props.addDocument?.(newCollection); + ffView.unprocessedDocs = []; + }); + + CollectionFreeFormView.collectionsWithUnprocessedInk.clear(); + if (checkResult) { return ((Doc.UserDoc().activeInkTool === tool && !GestureOverlay.Instance?.InkShape) || GestureOverlay.Instance?.InkShape === tool) ? Colors.MEDIUM_BLUE : "transparent"; @@ -716,6 +792,9 @@ ScriptingGlobals.add(function setActiveInkTool(tool: string, checkResult?: boole } else if (tool) { // pen or eraser if (Doc.UserDoc().activeInkTool === tool && !GestureOverlay.Instance.InkShape) { Doc.UserDoc().activeInkTool = InkTool.None; + } else if (tool == "write") { + console.log("write mode selected - create groupDoc here!") + // } else { Doc.UserDoc().activeInkTool = tool; GestureOverlay.Instance.InkShape = ""; -- cgit v1.2.3-70-g09d2