From e5905220a84a62fff36965a3bf74a55b793ae31b Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 29 Sep 2021 11:26:58 -0400
Subject: fixed filling of curves.  added toggling of brokenindex with
 right-click.   changed look of ink handles to be lighter weight and to
 reflect brokenindex sttate

---
 src/client/views/InkControlPtHandles.tsx | 95 ++++++++++++++++++--------------
 1 file changed, 53 insertions(+), 42 deletions(-)

(limited to 'src/client/views/InkControlPtHandles.tsx')

diff --git a/src/client/views/InkControlPtHandles.tsx b/src/client/views/InkControlPtHandles.tsx
index 898c3bf26..f80aca268 100644
--- a/src/client/views/InkControlPtHandles.tsx
+++ b/src/client/views/InkControlPtHandles.tsx
@@ -10,6 +10,7 @@ import { Transform } from "../util/Transform";
 import { UndoManager } from "../util/UndoManager";
 import { Colors } from "./global/globalEnums";
 import { InkStrokeProperties } from "./InkStrokeProperties";
+import { List } from "../../fields/List";
 
 export interface InkControlProps {
     inkDoc: Doc;
@@ -24,6 +25,8 @@ export interface InkControlProps {
 export class InkControlPtHandles extends React.Component<InkControlProps> {
 
     @observable private _overControl = -1;
+
+    @observable controlUndo: UndoManager.Batch | undefined;
     /**
      * Handles the movement of a selected control point when the user clicks and drags.
      * @param controlIndex The index of the currently selected control point.
@@ -31,34 +34,40 @@ export class InkControlPtHandles extends React.Component<InkControlProps> {
     @action
     onControlDown = (e: React.PointerEvent, controlIndex: number): void => {
         if (InkStrokeProperties.Instance) {
-            var controlUndo: UndoManager.Batch | undefined;
             const screenScale = this.props.ScreenToLocalTransform().Scale;
             const order = controlIndex % 4;
             const handleIndexA = ((order === 3 ? controlIndex - 1 : controlIndex - 2) + this.props.inkCtrlPoints.length) % this.props.inkCtrlPoints.length;
             const handleIndexB = (order === 3 ? controlIndex + 2 : controlIndex + 1) % this.props.inkCtrlPoints.length;
             const brokenIndices = Cast(this.props.inkDoc.brokenInkIndices, listSpec("number"));
             setupMoveUpEvents(this, e,
-                (e: PointerEvent, down: number[], delta: number[]) => {
-                    if (!controlUndo) controlUndo = UndoManager.StartBatch("drag ink ctrl pt");
+                action((e: PointerEvent, down: number[], delta: number[]) => {
+                    if (!this.controlUndo) this.controlUndo = UndoManager.StartBatch("drag ink ctrl pt");
                     InkStrokeProperties.Instance?.moveControl(-delta[0] * screenScale, -delta[1] * screenScale, controlIndex);
                     return false;
-                },
-                () => {
-                    controlUndo?.end();
+                }),
+                action(() => {
+                    this.controlUndo?.end();
+                    this.controlUndo = undefined;
                     UndoManager.FilterBatches(["data", "x", "y", "width", "height"]);
-                },
+                }),
                 action((e: PointerEvent, doubleTap: boolean | undefined) => {
                     const equivIndex = controlIndex === 0 ? this.props.inkCtrlPoints.length - 1 : controlIndex === this.props.inkCtrlPoints.length - 1 ? 0 : controlIndex;
-                    if (doubleTap) {
-                        if (brokenIndices?.includes(equivIndex)) {
-                            if (!controlUndo) controlUndo = UndoManager.StartBatch("make smooth");
-                            InkStrokeProperties.Instance?.snapHandleTangent(equivIndex, handleIndexA, handleIndexB);
-                        }
-                        if (equivIndex !== controlIndex && brokenIndices?.includes(controlIndex)) {
-                            if (!controlUndo) controlUndo = UndoManager.StartBatch("make smooth");
-                            InkStrokeProperties.Instance?.snapHandleTangent(controlIndex, handleIndexA, handleIndexB);
+                    if (doubleTap || e.button === 2) {
+                        if (!brokenIndices?.includes(equivIndex) && !brokenIndices?.includes(controlIndex)) {
+                            if (brokenIndices) brokenIndices.push(controlIndex);
+                            else this.props.inkDoc.brokenInkIndices = new List<number>([controlIndex]);
+                        } else {
+                            if (brokenIndices?.includes(equivIndex)) {
+                                if (!this.controlUndo) this.controlUndo = UndoManager.StartBatch("make smooth");
+                                InkStrokeProperties.Instance?.snapHandleTangent(equivIndex, handleIndexA, handleIndexB);
+                            }
+                            if (equivIndex !== controlIndex && brokenIndices?.includes(controlIndex)) {
+                                if (!this.controlUndo) this.controlUndo = UndoManager.StartBatch("make smooth");
+                                InkStrokeProperties.Instance?.snapHandleTangent(controlIndex, handleIndexA, handleIndexB);
+                            }
                         }
-                        controlUndo?.end();
+                        this.controlUndo?.end();
+                        this.controlUndo = undefined;
                     }
                 }));
         }
@@ -92,9 +101,6 @@ export class InkControlPtHandles extends React.Component<InkControlProps> {
     }
 
     render() {
-        const formatInstance = InkStrokeProperties.Instance;
-        if (!formatInstance) return (null);
-
         // Accessing the current ink's data and extracting all control points.
         const scrData = this.props.screenCtrlPoints;
         const sreenCtrlPoints: ControlPoint[] = [];
@@ -111,41 +117,46 @@ export class InkControlPtHandles extends React.Component<InkControlProps> {
         }
 
         const screenSpaceLineWidth = this.props.screenSpaceLineWidth;
-        const rectHdlSize = (i: number) => this._overControl === i ? screenSpaceLineWidth * 6 : screenSpaceLineWidth * 4;
-
         const nearestScreenPt = this.props.nearestScreenPt();
+        const TagType = (broken?: boolean) => broken ? "rect" : "circle";
+        const hdl = (control: { X: number, Y: number, I: number }, scale: number, color: string) => {
+            const broken = Cast(this.props.inkDoc.brokenInkIndices, listSpec("number"))?.includes(control.I);
+            const Tag = TagType(broken) as keyof JSX.IntrinsicElements;
+            return <circle key={control.I.toString() + scale}
+                x={control.X - screenSpaceLineWidth * 3 * scale}
+                y={control.Y - screenSpaceLineWidth * 3 * scale}
+                cx={control.X}
+                cy={control.Y}
+                r={screenSpaceLineWidth * 2 * scale}
+                opacity={this.controlUndo ? 0.15 : 1}
+                height={screenSpaceLineWidth * 6 * scale}
+                width={screenSpaceLineWidth * 6 * scale}
+                strokeWidth={screenSpaceLineWidth / 2}
+                stroke={Colors.MEDIUM_BLUE}
+                fill={broken ? Colors.MEDIUM_BLUE : color}
+                onPointerDown={(e: any) => {
+                    this.changeCurrPoint(control.I);
+                    this.onControlDown(e, control.I);
+                }}
+                onMouseEnter={() => this.onEnterControl(control.I)}
+                onMouseLeave={this.onLeaveControl}
+                pointerEvents="all"
+                cursor="default"
+            />;
+        }
         return (<svg>
             {!nearestScreenPt ? (null) :
                 <circle key={"npt"}
                     cx={nearestScreenPt.X}
                     cy={nearestScreenPt.Y}
-                    r={screenSpaceLineWidth * 4}
+                    r={screenSpaceLineWidth * 2}
                     fill={"#00007777"}
                     stroke={"#00007777"}
                     strokeWidth={0}
                     pointerEvents="none"
-                    cursor="all-scroll"
                 />
             }
-            {sreenCtrlPoints.map((control, i) =>
-                <rect key={i}
-                    x={control.X - rectHdlSize(i) / 2}
-                    y={control.Y - rectHdlSize(i) / 2}
-                    height={rectHdlSize(i)}
-                    width={rectHdlSize(i)}
-                    strokeWidth={screenSpaceLineWidth / 2}
-                    stroke={Colors.MEDIUM_BLUE}
-                    fill={formatInstance?._currentPoint === control.I ? Colors.MEDIUM_BLUE : Colors.WHITE}
-                    onPointerDown={e => {
-                        this.changeCurrPoint(control.I);
-                        this.onControlDown(e, control.I);
-                    }}
-                    onMouseEnter={e => this.onEnterControl(i)}
-                    onMouseLeave={this.onLeaveControl}
-                    pointerEvents="all"
-                    cursor="default"
-                />
-            )}
+            {sreenCtrlPoints.map(control => hdl(control, this._overControl !== control.I ? 1 : 3 / 2, Colors.WHITE))}
         </svg>
         );
     }
-- 
cgit v1.2.3-70-g09d2

