From b88f3a79b4558b222864b7c925fd0d5086cdcea2 Mon Sep 17 00:00:00 2001
From: eleanor-park <eleanor_park@brown.edu>
Date: Thu, 11 Jul 2024 12:08:26 -0400
Subject: Revert "Merge branch 'eleanor-gptdraw' into master"

This reverts commit 4438e7fe202ff4091b26f073122e7866ec9abb46, reversing
changes made to 59ca918ea0918b41f1e2fa4b6acb8725ca9b44af.
---
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 242 ++++++---------------
 1 file changed, 71 insertions(+), 171 deletions(-)

(limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx')

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 8f8cb9083..d611db1f8 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,7 +1,7 @@
 /* eslint-disable react/jsx-props-no-spreading */
 /* eslint-disable jsx-a11y/click-events-have-key-events */
 /* eslint-disable jsx-a11y/no-static-element-interactions */
-import { Bezier, Point } from 'bezier-js';
+import { Bezier } from 'bezier-js';
 import { Colors } from 'browndash-components';
 import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
@@ -27,7 +27,6 @@ import { aggregateBounds, clamp, emptyFunction, intersectRect, Utils } from '../
 import { Docs } from '../../../documents/Documents';
 import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
 import { DocUtils } from '../../../documents/DocUtils';
-import { FitCurve, GenerateControlPoints } from '../../../util/bezierFit';
 import { DragManager } from '../../../util/DragManager';
 import { dropActionType } from '../../../util/DropActionTypes';
 import { CompileScript } from '../../../util/Scripting';
@@ -56,7 +55,6 @@ import { CollectionFreeFormPannableContents } from './CollectionFreeFormPannable
 import { CollectionFreeFormRemoteCursors } from './CollectionFreeFormRemoteCursors';
 import './CollectionFreeFormView.scss';
 import { MarqueeView } from './MarqueeView';
-import { DrawingOptions, SmartDrawHandler } from '../../smartdraw/SmartDrawHandler';
 
 @observer
 class CollectionFreeFormOverlayView extends React.Component<{ elements: () => ViewDefResult[] }> {
@@ -120,7 +118,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     @observable _panZoomTransition: number = 0; // sets the pan/zoom transform ease time- used by nudge(), focus() etc to smoothly zoom/pan.  set to 0 to use document's transition time or default of 0
     @observable _firstRender = false; // this turns off rendering of the collection's content so that there's instant feedback when a tab is switched of what content will be shown.  could be used for performance improvement
     @observable _showAnimTimeline = false;
-    @observable _showDrawingEditor = false;
     @observable _deleteList: DocumentView[] = [];
     @observable _timelineRef = React.createRef<Timeline>();
     @observable _marqueeViewRef = React.createRef<MarqueeView>();
@@ -500,30 +497,28 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             if (!this.Document.isGroup) {
                 // group freeforms don't pan when dragged -- instead let the event go through to allow the group itself to drag
                 // prettier-ignore
-                const hit = this._clusters.handlePointerDown(this.screenToFreeformContentsXf.transformPoint(e.clientX, e.clientY));
                 switch (Doc.ActiveTool) {
-                    case InkTool.Highlighter:
-                    case InkTool.Write:
-                    case InkTool.Pen:
-                        break; // the GestureOverlay handles ink stroke input -- either as gestures, or drying as ink strokes that are added to document views
+                    case InkTool.Highlighter: break;
+                    case InkTool.Write: break;
+                    case InkTool.Pen: break; // the GestureOverlay handles ink stroke input -- either as gestures, or drying as ink strokes that are added to document views
                     case InkTool.StrokeEraser:
                     case InkTool.SegmentEraser:
+                        this._batch = UndoManager.StartBatch('collectionErase');
+                        this._eraserPts.length = 0;
+                        setupMoveUpEvents(this, e, this.onEraserMove, this.onEraserUp, emptyFunction);
+                        break;
                     case InkTool.RadiusEraser:
                         this._batch = UndoManager.StartBatch('collectionErase');
                         this._eraserPts.length = 0;
-                        setupMoveUpEvents(this, e, this.onEraserMove, this.onEraserUp, this.onEraserClick, hit !== -1);
-                        e.stopPropagation();
+                        setupMoveUpEvents(this, e, this.onRadiusEraserMove, this.onEraserUp, emptyFunction);
                         break;
-                    case InkTool.SmartDraw:
-                        setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, this.showSmartDraw, hit !== -1);
-                        e.stopPropagation();
                     case InkTool.None:
                         if (!(this._props.layoutEngine?.() || StrCast(this.layoutDoc._layoutEngine))) {
                             const hit = this._clusters.handlePointerDown(this.screenToFreeformContentsXf.transformPoint(e.clientX, e.clientY));
                             setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, emptyFunction, hit !== -1, false);
                         }
                         break;
-                    default:
+                    default: 
                 }
             }
         }
@@ -574,7 +569,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             }
         }
     };
-
     @action
     onEraserUp = (): void => {
         this._deleteList.lastElement()?._props.removeDocument?.(this._deleteList.map(ink => ink.Document));
@@ -615,48 +609,34 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     _eraserLock = 0;
     _eraserPts: number[][] = []; // keep track of the last few eraserPts to make the eraser circle 'stretch'
 
-    erase = (e: PointerEvent, delta: number[]) => {
-        e.stopImmediatePropagation();
+    /**
+     * Erases strokes by intersecting them with an invisible "eraser stroke".
+     *  By default this iterates through all intersected ink strokes, determines their segmentation, draws back the non-intersected segments,
+     * and deletes the original stroke.
+     */
+    @action
+    onEraserMove = (e: PointerEvent, down: number[], delta: number[]) => {
         const currPoint = { X: e.clientX, Y: e.clientY };
         this._eraserPts.push([currPoint.X, currPoint.Y]);
         this._eraserPts = this._eraserPts.slice(Math.max(0, this._eraserPts.length - 5));
-        if (Doc.ActiveTool === InkTool.RadiusEraser) {
-            const strokeMap: Map<DocumentView, number[]> = this.getRadiusEraserIntersections({ X: currPoint.X - delta[0], Y: currPoint.Y - delta[1] }, currPoint);
-            strokeMap.forEach((intersects, stroke) => {
-                if (!this._deleteList.includes(stroke)) {
-                    this._deleteList.push(stroke);
-                    SetActiveInkWidth(StrCast(stroke.Document.stroke_width?.toString()) || '1');
-                    SetActiveInkColor(StrCast(stroke.Document.color?.toString()) || 'black');
-                    const segments = this.radiusErase(stroke, intersects.sort());
-                    segments?.forEach(segment =>
-                        this.forceStrokeGesture(
-                            e,
-                            Gestures.Stroke,
-                            segment.reduce((data, curve) => [...data, ...curve.points.map(p => stroke.ComponentView?.ptToScreen?.({ X: p.x, Y: p.y }) ?? { X: 0, Y: 0 })], [] as PointData[])
-                        )
-                    );
-                }
-                stroke.layoutDoc.opacity = 0;
-                stroke.layoutDoc.dontIntersect = true;
-            });
-        } else {
-            this.getEraserIntersections({ X: currPoint.X - delta[0], Y: currPoint.Y - delta[1] }, currPoint).forEach(intersect => {
-                if (!this._deleteList.includes(intersect.inkView)) {
-                    this._deleteList.push(intersect.inkView);
-                    SetActiveInkWidth(StrCast(intersect.inkView.Document.stroke_width?.toString()) || '1');
-                    SetActiveInkColor(StrCast(intersect.inkView.Document.color?.toString()) || 'black');
-                    // create a new curve by appending all curves of the current segment together in order to render a single new stroke.
-                    if (Doc.ActiveTool !== InkTool.StrokeEraser) {
-                        // this._eraserLock++;
-                        const segments = this.segmentErase(intersect.inkView, intersect.t); // intersect.t is where the eraser intersected the ink stroke - want to remove the segment that starts at the intersection just before this t value and goes to the one just after it
-                        const newStrokes = segments?.map(segment => {
-                            const points = segment.reduce((data, curve) => [...data, ...curve.points.map(p => intersect.inkView.ComponentView?.ptToScreen?.({ X: p.x, Y: p.y }) ?? { X: 0, Y: 0 })], [] as PointData[]);
-                            const bounds = InkField.getBounds(points);
-                            const B = this.screenToFreeformContentsXf.transformBounds(bounds.left, bounds.top, bounds.width, bounds.height);
-                            const inkWidth = ActiveInkWidth() * this.ScreenToLocalBoxXf().Scale;
-                            return Docs.Create.InkDocument(
-                                points,
-                                { title: 'stroke',
+        // if (this._eraserLock) return false; // leaving this commented out in case the idea is revisited in the future
+        this.getEraserIntersections({ X: currPoint.X - delta[0], Y: currPoint.Y - delta[1] }, currPoint).forEach(intersect => {
+            if (!this._deleteList.includes(intersect.inkView)) {
+                this._deleteList.push(intersect.inkView);
+                SetActiveInkWidth(StrCast(intersect.inkView.Document.stroke_width?.toString()) || '1');
+                SetActiveInkColor(StrCast(intersect.inkView.Document.color?.toString()) || 'black');
+                // create a new curve by appending all curves of the current segment together in order to render a single new stroke.
+                if (Doc.ActiveTool !== InkTool.StrokeEraser) {
+                    // this._eraserLock++;
+                    const segments = this.segmentErase(intersect.inkView, intersect.t); // intersect.t is where the eraser intersected the ink stroke - want to remove the segment that starts at the intersection just before this t value and goes to the one just after it
+                    const newStrokes = segments?.map(segment => {
+                        const points = segment.reduce((data, curve) => [...data, ...curve.points.map(p => intersect.inkView.ComponentView?.ptToScreen?.({ X: p.x, Y: p.y }) ?? { X: 0, Y: 0 })], [] as PointData[]);
+                        const bounds = InkField.getBounds(points);
+                        const B = this.screenToFreeformContentsXf.transformBounds(bounds.left, bounds.top, bounds.width, bounds.height);
+                        const inkWidth = ActiveInkWidth() * this.ScreenToLocalBoxXf().Scale;
+                        return Docs.Create.InkDocument(
+                            points,
+                            { title: 'stroke',
                             x: B.x - inkWidth / 2,
                             y: B.y - inkWidth / 2,
                             _width: B.width + inkWidth,
@@ -675,30 +655,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                     newStrokes && this.addDocument?.(newStrokes);
                     // setTimeout(() => this._eraserLock--);
                 }
-            });
-        }
-        return false;
-    };
-
-    /**
-     * Erases strokes by intersecting them with an invisible "eraser stroke".
-     *  By default this iterates through all intersected ink strokes, determines their segmentation, draws back the non-intersected segments,
-     * and deletes the original stroke.
-     */
-    @action
-    onEraserMove = (e: PointerEvent, down: number[], delta: number[]) => {
-        this.erase(e, delta);
-        // if (this._eraserLock) return false; // leaving this commented out in case the idea is revisited in the future
+                // Lower ink opacity to give the user a visual indicator of deletion.
+                intersect.inkView.layoutDoc.opacity = 0;
+                intersect.inkView.layoutDoc.dontIntersect = true;
+            }
+        });
         return false;
     };
 
-    @action
-    onEraserClick = (e: PointerEvent, doubleTap?: boolean) => {
-        e.preventDefault();
-        e.stopImmediatePropagation();
-        this.erase(e, [0, 0]);
-    };
-
     /**
      * Erases strokes by intersecting them with a circle of variable radius. Essentially creates an InkField for the
      * eraser circle, then determines its intersections with other ink strokes. Each stroke's DocumentView and its
@@ -708,32 +672,32 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
      * @param delta
      * @returns
      */
-    // @action
-    // onRadiusEraserMove = (e: PointerEvent, down: number[], delta: number[]) => {
-    //     const currPoint = { X: e.clientX, Y: e.clientY };
-    //     this._eraserPts.push([currPoint.X, currPoint.Y]);
-    //     this._eraserPts = this._eraserPts.slice(Math.max(0, this._eraserPts.length - 5));
-    //     const strokeMap: Map<DocumentView, number[]> = this.getRadiusEraserIntersections({ X: currPoint.X - delta[0], Y: currPoint.Y - delta[1] }, currPoint);
-
-    //     strokeMap.forEach((intersects, stroke) => {
-    //         if (!this._deleteList.includes(stroke)) {
-    //             this._deleteList.push(stroke);
-    //             SetActiveInkWidth(StrCast(stroke.Document.stroke_width?.toString()) || '1');
-    //             SetActiveInkColor(StrCast(stroke.Document.color?.toString()) || 'black');
-    //             const segments = this.radiusErase(stroke, intersects.sort());
-    //             segments?.forEach(segment =>
-    //                 this.forceStrokeGesture(
-    //                     e,
-    //                     Gestures.Stroke,
-    //                     segment.reduce((data, curve) => [...data, ...curve.points.map(p => stroke.ComponentView?.ptToScreen?.({ X: p.x, Y: p.y }) ?? { X: 0, Y: 0 })], [] as PointData[])
-    //                 )
-    //             );
-    //         }
-    //         stroke.layoutDoc.opacity = 0;
-    //         stroke.layoutDoc.dontIntersect = true;
-    //     });
-    //     return false;
-    // };
+    @action
+    onRadiusEraserMove = (e: PointerEvent, down: number[], delta: number[]) => {
+        const currPoint = { X: e.clientX, Y: e.clientY };
+        this._eraserPts.push([currPoint.X, currPoint.Y]);
+        this._eraserPts = this._eraserPts.slice(Math.max(0, this._eraserPts.length - 5));
+        const strokeMap: Map<DocumentView, number[]> = this.getRadiusEraserIntersections({ X: currPoint.X - delta[0], Y: currPoint.Y - delta[1] }, currPoint);
+
+        strokeMap.forEach((intersects, stroke) => {
+            if (!this._deleteList.includes(stroke)) {
+                this._deleteList.push(stroke);
+                SetActiveInkWidth(StrCast(stroke.Document.stroke_width?.toString()) || '1');
+                SetActiveInkColor(StrCast(stroke.Document.color?.toString()) || 'black');
+                const segments = this.radiusErase(stroke, intersects.sort());
+                segments?.forEach(segment =>
+                    this.forceStrokeGesture(
+                        e,
+                        Gestures.Stroke,
+                        segment.reduce((data, curve) => [...data, ...curve.points.map(p => stroke.ComponentView?.ptToScreen?.({ X: p.x, Y: p.y }) ?? { X: 0, Y: 0 })], [] as PointData[])
+                    )
+                );
+            }
+            stroke.layoutDoc.opacity = 0;
+            stroke.layoutDoc.dontIntersect = true;
+        });
+        return false;
+    };
 
     forceStrokeGesture = (e: PointerEvent, gesture: Gestures, points: InkData, text?: any) => {
         this.onGesture(e, new GestureUtils.GestureEvent(gesture, points, InkField.getBounds(points), text));
@@ -764,7 +728,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         // increase radius slightly based on the erased stroke's width, added to make eraser look more realistic
         const radius = ActiveEraserWidth() + 5 + inkStrokeWidth * 0.1; // add 5 to prevent eraser from being too small
         const c = 0.551915024494; // circle tangent length to side ratio
-        const movement = { x: Math.max(endInkCoordsIn.X - startInkCoordsIn.X, 1), y: Math.max(endInkCoordsIn.Y - startInkCoordsIn.Y, 1) };
+        const movement = { x: endInkCoordsIn.X - startInkCoordsIn.X, y: endInkCoordsIn.Y - startInkCoordsIn.Y };
         const moveLen = Math.sqrt(movement.x ** 2 + movement.y ** 2);
         const direction = { x: (movement.x / moveLen) * radius, y: (movement.y / moveLen) * radius };
         const normal    = { x: -direction.y, y: direction.x }; // prettier-ignore
@@ -1274,60 +1238,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         return tVals;
     };
 
-    @action
-    showSmartDraw = (e: PointerEvent, doubleTap?: boolean) => {
-        SmartDrawHandler.Instance.displaySmartDrawHandler(e.pageX, e.pageY, this.createDrawing, this.removeDrawing);
-    };
-
-    _drawing: Doc[] = [];
-    @undoBatch
-    createDrawing = (e: React.PointerEvent<Element>, strokeData: [InkData, string, string][], opts: DrawingOptions, gptRes: string, containerDoc?: Doc) => {
-        strokeData.forEach((stroke: [InkData, string, string]) => {
-            const bounds = InkField.getBounds(stroke[0]);
-            const B = this.screenToFreeformContentsXf.transformBounds(bounds.left, bounds.top, bounds.width, bounds.height);
-            const inkWidth = ActiveInkWidth() * this.ScreenToLocalBoxXf().Scale;
-            const inkDoc = Docs.Create.InkDocument(
-                stroke[0],
-                { title: 'stroke',
-                    x: B.x - inkWidth / 2,
-                    y: B.y - inkWidth / 2,
-                    _width: B.width + inkWidth,
-                    _height: B.height + inkWidth,
-                    stroke_showLabel: BoolCast(Doc.UserDoc().activeInkHideTextLabels)}, // prettier-ignore
-                inkWidth,
-                stroke[1],
-                undefined,
-                stroke[2] === 'none' ? undefined : stroke[2]
-            );
-            this._drawing.push(inkDoc);
-            this.addDocument(inkDoc);
-        });
-        const collection = this._marqueeViewRef.current?.collection(undefined, true, this._drawing);
-        if (collection) {
-            const docData = collection[DocData];
-            docData.title = opts.text;
-            docData.drawingInput = opts.text;
-            docData.drawingComplexity = opts.complexity;
-            docData.drawingColored = opts.autoColor;
-            docData.drawingSize = opts.size;
-            docData.drawingData = gptRes;
-        }
-        this._batch?.end();
-    };
-
-    removeDrawing = (doc?: Doc) => {
-        this._batch = UndoManager.StartBatch('regenerateDrawing');
-        if (doc) {
-            const docData: Doc = doc[DocData];
-            const children = docData.data as unknown as Doc[];
-            this._props.removeDocument?.(doc);
-            this._props.removeDocument?.(children);
-        } else {
-            this._props.removeDocument?.(this._drawing);
-        }
-        this._drawing = [];
-    };
-
     @action
     zoom = (pointX: number, pointY: number, deltaY: number): void => {
         if (this.Document.isGroup || this.Document[(this._props.viewField ?? '_') + 'freeform_noZoom']) return;
@@ -1921,10 +1831,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
 
     @action
     onCursorMove = (e: React.PointerEvent) => {
-        const locPt = this.ScreenToLocalBoxXf().transformPoint(e.clientX, e.clientY);
-        this._eraserX = locPt[0];
-        this._eraserY = locPt[1];
-        // Doc.ActiveTool === InkTool.RadiusEraser ? this._childPointerEvents = 'none' : this._childPointerEvents = 'all'
+        this._eraserX = e.clientX;
+        this._eraserY = e.clientY;
         //  super.setCursorPosition(this.getTransform().transformPoint(e.clientX, e.clientY));
     };
 
@@ -2031,14 +1939,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                 }),
                 icon: 'eye',
             });
-        optionItems.push({
-            description: (this._showDrawingEditor ? 'Close' : 'Show') + ' Drawing Editor',
-            event: action(() => {
-                this._showDrawingEditor = !this._showDrawingEditor;
-                this._showDrawingEditor ? SmartDrawHandler.Instance.displayRegenerate(this._downX, this._downY - 10, this.createDrawing, this.removeDrawing) : SmartDrawHandler.Instance.hideRegenerate();
-            }),
-            icon: 'pen-to-square',
-        });
         this._props.renderDepth &&
             optionItems.push({
                 description: 'Use Background Color as Default',
@@ -2243,8 +2143,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                         onPointerMove={this.onCursorMove}
                         style={{
                             position: 'fixed',
-                            left: this._eraserX,
-                            top: this._eraserY,
+                            left: this._eraserX - 60,
+                            top: this._eraserY - 100,
                             width: (ActiveEraserWidth() + 5) * 2,
                             height: (ActiveEraserWidth() + 5) * 2,
                             borderRadius: '50%',
-- 
cgit v1.2.3-70-g09d2

