From 4c768162e0436115a05b9c8b0e4d837d626d45ba Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 30 Oct 2024 18:54:52 -0400
Subject: reworked how context menu buttons for ink and text work. added
 disableMixBlend for making transparent docs not use 'multiply'.

---
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 71 +++++++++++++---------
 1 file changed, 42 insertions(+), 29 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 ff711314b..f2a5780c5 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -10,7 +10,7 @@ import { DateField } from '../../../../fields/DateField';
 import { Doc, DocListCast, Field, FieldType, Opt, StrListCast } from '../../../../fields/Doc';
 import { DocData, Height, Width } from '../../../../fields/DocSymbols';
 import { Id } from '../../../../fields/FieldSymbols';
-import { InkData, InkField, InkTool, Segment } from '../../../../fields/InkField';
+import { InkData, InkEraserTool, InkField, InkInkTool, InkTool, Segment } from '../../../../fields/InkField';
 import { List } from '../../../../fields/List';
 import { RichTextField } from '../../../../fields/RichTextField';
 import { listSpec } from '../../../../fields/Schema';
@@ -36,7 +36,20 @@ import { ContextMenu } from '../../ContextMenu';
 import { InkingStroke } from '../../InkingStroke';
 import { CollectionFreeFormDocumentView } from '../../nodes/CollectionFreeFormDocumentView';
 import { SchemaCSVPopUp } from '../../nodes/DataVizBox/SchemaCSVPopUp';
-import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveEraserWidth, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, DocumentView, SetActiveInkColor, SetActiveInkWidth } from '../../nodes/DocumentView';
+import {
+    ActiveInkArrowEnd,
+    ActiveInkArrowStart,
+    ActiveInkDash,
+    ActiveEraserWidth,
+    ActiveInkFillColor,
+    ActiveInkBezierApprox,
+    ActiveInkColor,
+    ActiveInkWidth,
+    ActiveIsInkMask,
+    DocumentView,
+    SetActiveInkColor,
+    SetActiveInkWidth,
+} from '../../nodes/DocumentView';
 import { FieldViewProps } from '../../nodes/FieldView';
 import { FocusViewOptions } from '../../nodes/FocusViewOptions';
 import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
@@ -497,13 +510,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                 // 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:
+                    case InkTool.Ink:
                         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:
-                    case InkTool.RadiusEraser:
+                    case InkTool.Eraser:
                         this._batch = UndoManager.StartBatch('collectionErase');
                         this._eraserPts.length = 0;
                         setupMoveUpEvents(this, e, this.onEraserMove, this.onEraserUp, this.onEraserClick, hit !== -1);
@@ -543,7 +552,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                 const { points } = ge;
                 const B = this.screenToFreeformContentsXf.transformBounds(ge.bounds.left, ge.bounds.top, ge.bounds.width, ge.bounds.height);
                 const inkDoc = this.createInkDoc(points, B);
-                if (Doc.ActiveTool === InkTool.Write) {
+                if (Doc.ActiveInk === InkInkTool.Highlight) inkDoc[DocData].backgroundColor = 'transparent';
+                if (Doc.ActiveInk === InkInkTool.Write) {
                     this.unprocessedDocs.push(inkDoc);
                     CollectionFreeFormView.collectionsWithUnprocessedInk.add(this);
                 }
@@ -606,7 +616,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         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) {
+        if (Doc.ActiveEraser === InkEraserTool.Radius) {
             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)) {
@@ -614,13 +624,16 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                     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[])
-                        )
-                    );
+                    segments?.forEach(segment => {
+                        const points = segment.reduce((data, curve) => [...data, ...curve.points.map(p => stroke.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 inkDoc = this.createInkDoc(points, B);
+                        ['color', 'fillColor', 'stroke_width', 'stroke_dash', 'stroke_bezier'].forEach(field => {
+                            inkDoc[DocData][field] = stroke.dataDoc[field];
+                        });
+                        this.addDocument(inkDoc);
+                    });
                 }
                 stroke.layoutDoc.opacity = 0;
                 stroke.layoutDoc.dontIntersect = true;
@@ -632,7 +645,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                     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) {
+                    if (Doc.ActiveEraser !== InkEraserTool.Stroke) {
                         // 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 => {
@@ -1195,14 +1208,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                 y: B.y - inkWidth / 2,
                 _width: B.width + inkWidth,
                 _height: B.height + inkWidth,
-                stroke_showLabel: BoolCast(Doc.UserDoc().activeInkHideTextLabels)}, // prettier-ignore
+                stroke_showLabel: !BoolCast(Doc.UserDoc().activeHideTextLabels)}, // prettier-ignore
             inkWidth,
             ActiveInkColor(),
             ActiveInkBezierApprox(),
-            ActiveFillColor(),
-            ActiveArrowStart(),
-            ActiveArrowEnd(),
-            ActiveDash(),
+            ActiveInkFillColor(),
+            ActiveInkArrowStart(),
+            ActiveInkArrowEnd(),
+            ActiveInkDash(),
             ActiveIsInkMask()
         );
     };
@@ -1235,14 +1248,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                     y: B.y - inkWidth / 2,
                     _width: B.width + inkWidth,
                     _height: B.height + inkWidth,
-                    stroke_showLabel: BoolCast(Doc.UserDoc().activeInkHideTextLabels)}, // prettier-ignore
+                    stroke_showLabel: BoolCast(Doc.UserDoc().activeHideTextLabels)}, // prettier-ignore
                 inkWidth,
                 opts.autoColor ? stroke[1] : ActiveInkColor(),
                 ActiveInkBezierApprox(),
-                stroke[2] === 'none' ? ActiveFillColor() : stroke[2],
-                ActiveArrowStart(),
-                ActiveArrowEnd(),
-                ActiveDash(),
+                stroke[2] === 'none' ? ActiveInkFillColor() : stroke[2],
+                ActiveInkArrowStart(),
+                ActiveInkArrowEnd(),
+                ActiveInkDash(),
                 ActiveIsInkMask()
             );
             this._drawing.push(inkDoc);
@@ -2195,7 +2208,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                     width: `${100 / this.nativeDimScaling}%`,
                     height: this._props.getScrollHeight?.() ?? `${100 / this.nativeDimScaling}%`,
                 }}>
-                {Doc.ActiveTool === InkTool.RadiusEraser && this._showEraserCircle && (
+                {Doc.ActiveTool === InkTool.Eraser && Doc.ActiveEraser === InkEraserTool.Radius && this._showEraserCircle && (
                     <div
                         onPointerMove={this.onCursorMove}
                         style={{
-- 
cgit v1.2.3-70-g09d2

