From 34d43b0d7ff1829514566e2b6b8514f6176e7c60 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Tue, 9 Jun 2020 11:48:22 -0400
Subject: fixed keyFrame animation positioning issues when adding a doc at t !=
 0. added isInkMask field and inkStroke menu option to create an ink mask. 
 added cantLeaveCollection flag.

---
 .../views/nodes/CollectionFreeFormDocumentView.tsx      | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

(limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx')

diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 910aa744d..77a2e04e6 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -36,7 +36,8 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
         return min + rnd * (max - min);
     }
     get displayName() { return "CollectionFreeFormDocumentView(" + this.rootDoc.title + ")"; } // this makes mobx trace() statements more descriptive
-    get transform() { return `scale(${this.props.ContentScaling()}) translate(${this.X}px, ${this.Y}px) rotate(${this.random(-1, 1) * this.props.jitterRotation}deg)`; }
+    get maskCentering() { return this.props.Document.isInkMask ? 2500 : 0; }
+    get transform() { return `scale(${this.props.ContentScaling()}) translate(${this.X - this.maskCentering}px, ${this.Y - this.maskCentering}px) rotate(${this.random(-1, 1) * this.props.jitterRotation}deg)`; }
     get X() { return this.dataProvider ? this.dataProvider.x : (this.Document.x || 0); }
     get Y() { return this.dataProvider ? this.dataProvider.y : (this.Document.y || 0); }
     get Opacity() { return this.dataProvider ? this.dataProvider.opacity : Cast(this.layoutDoc.opacity, "number", null); }
@@ -79,8 +80,6 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
 
     public static setValues(time: number, d: Doc, x?: number, y?: number, opacity?: number) {
         const timecode = Math.round(time);
-        Cast(d["x-indexed"], listSpec("number"), [])[Math.max(0, timecode - 1)] = x as any as number;
-        Cast(d["y-indexed"], listSpec("number"), [])[Math.max(0, timecode - 1)] = y as any as number;
         Cast(d["x-indexed"], listSpec("number"), [])[timecode] = x as any as number;
         Cast(d["y-indexed"], listSpec("number"), [])[timecode] = y as any as number;
         Cast(d["opacity-indexed"], listSpec("number"), null)[timecode] = opacity as any as number;
@@ -110,12 +109,12 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
             const xlist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]);
             const ylist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]);
             const olist = new List<number>(numberRange(timecode + 1).map(t => progressivize && t < i ? 0 : 1));
-            xlist[Math.max(curTimecode - 1, 0)] = xlist[curTimecode] = NumCast(doc.x);
-            ylist[Math.max(curTimecode - 1, 0)] = ylist[curTimecode] = NumCast(doc.y);
+            xlist[curTimecode] = NumCast(doc.x);
+            ylist[curTimecode] = NumCast(doc.y);
             doc["x-indexed"] = xlist;
             doc["y-indexed"] = ylist;
             doc["opacity-indexed"] = olist;
-            doc.activeFrame = ComputedField.MakeFunction("self.context ? (self.context.currentFrame||0) : 0");
+            doc.activeFrame = ComputedField.MakeFunction("self.context?.currentFrame||0");
             doc.x = ComputedField.MakeInterpolated("x", "activeFrame");
             doc.y = ComputedField.MakeInterpolated("y", "activeFrame");
             doc.opacity = ComputedField.MakeInterpolated("opacity", "activeFrame");
@@ -151,12 +150,12 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
                 outline: this.Highlight ? "orange solid 2px" : "",
                 transform: this.transform,
                 transition: this.props.transition ? this.props.transition : this.dataProvider ? this.dataProvider.transition : StrCast(this.layoutDoc.transition),
-                width: this.width,
-                height: this.height,
+                width: this.props.Document.isInkMask ? 5000 : this.width,
+                height: this.props.Document.isInkMask ? 5000 : this.height,
                 zIndex: this.ZInd,
                 mixBlendMode: StrCast(this.layoutDoc.mixBlendMode) as any,
                 display: this.ZInd === -99 ? "none" : undefined,
-                pointerEvents: this.props.Document.isBackground || this.Opacity === 0 ? "none" : this.props.pointerEvents ? "all" : undefined
+                pointerEvents: this.props.Document.isBackground || this.Opacity === 0 || this.props.Document.isInkMask ? "none" : this.props.pointerEvents ? "all" : undefined
             }} >
             {Doc.UserDoc().renderStyle !== "comic" ? (null) :
                 <div style={{ width: "100%", height: "100%", position: "absolute" }}>
-- 
cgit v1.2.3-70-g09d2


From 1daca67ea2a574b16c02b185d66f5724651ba235 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Wed, 10 Jun 2020 15:55:05 -0400
Subject: changed how ink is highlighted when selected.

---
 src/client/util/InteractionUtils.tsx               |  4 ++-
 src/client/views/GestureOverlay.tsx                |  2 ++
 src/client/views/InkingStroke.tsx                  | 35 ++++++++++++++++++----
 .../collections/collectionFreeForm/MarqueeView.tsx |  9 +++---
 .../views/nodes/CollectionFreeFormDocumentView.tsx |  3 +-
 src/client/views/nodes/DocumentView.tsx            |  2 +-
 6 files changed, 43 insertions(+), 12 deletions(-)

(limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx')

diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx
index 3948611f0..81f9b9362 100644
--- a/src/client/util/InteractionUtils.tsx
+++ b/src/client/util/InteractionUtils.tsx
@@ -89,7 +89,7 @@ export namespace InteractionUtils {
         return myTouches;
     }
 
-    export function CreatePolyline(points: { X: number, Y: number }[], left: number, top: number, color: string, width: string, bezier: string, scalex: number, scaley: number, shape: string) {
+    export function CreatePolyline(points: { X: number, Y: number }[], left: number, top: number, color: string, width: string, bezier: string, scalex: number, scaley: number, shape: string, pevents: string, drawHalo: boolean) {
         var pts = "";
         if (shape) {
             //if any of the shape are true
@@ -120,7 +120,9 @@ export namespace InteractionUtils {
             <polyline
                 points={pts}
                 style={{
+                    filter: drawHalo ? "url(#dangerShine)" : undefined,
                     fill: "none",
+                    pointerEvents: pevents as any,
                     stroke: color ?? "rgb(0, 0, 0)",
                     strokeWidth: parseInt(width),
                     strokeLinejoin: "round",
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 3384b5fce..d239a1d6f 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -674,6 +674,8 @@ export default class GestureOverlay extends Touchable {
                     this._points = [];
                 }
             }
+        } else {
+            this._points = [];
         }
         document.removeEventListener("pointermove", this.onPointerMove);
         document.removeEventListener("pointerup", this.onPointerUp);
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index b545ede54..acbfde5a1 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -16,6 +16,7 @@ import { FieldView, FieldViewProps } from "./nodes/FieldView";
 import React = require("react");
 import { Scripting } from "../util/Scripting";
 import { Doc } from "../../fields/Doc";
+import { Id } from "../../fields/FieldSymbols";
 
 library.add(faPaintBrush);
 
@@ -44,15 +45,21 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
         const height = bottom - top;
         const scaleX = this.props.PanelWidth() / width;
         const scaleY = this.props.PanelHeight() / height;
+        const strokeWidth = Number(StrCast(this.layoutDoc.strokeWidth, ActiveInkWidth()));
+        const strokeColor = StrCast(this.layoutDoc.color, ActiveInkColor());
         const points = InteractionUtils.CreatePolyline(data, left, top,
-            StrCast(this.layoutDoc.color, ActiveInkColor()),
-            StrCast(this.layoutDoc.strokeWidth, ActiveInkWidth()),
-            StrCast(this.layoutDoc.strokeBezier, ActiveInkBezierApprox()), scaleX, scaleY, "");
+            strokeColor,
+            strokeWidth.toString(),
+            StrCast(this.layoutDoc.strokeBezier, ActiveInkBezierApprox()), scaleX, scaleY, "", "none", this.props.isSelected() && strokeWidth <= 5);
+        const hpoints = InteractionUtils.CreatePolyline(data, left, top,
+            this.props.isSelected() && strokeWidth > 5 ? strokeColor : "transparent",
+            (strokeWidth + 15).toString(),
+            StrCast(this.layoutDoc.strokeBezier, ActiveInkBezierApprox()), scaleX, scaleY, "", this.props.active() ? "visiblestroke" : "none", false);
         return (
             <svg className="inkingStroke"
                 width={width}
                 height={height}
-                style={{ mixBlendMode: this.layoutDoc.tool === InkTool.Highlighter ? "multiply" : "unset" }}
+                style={{ pointerEvents: "none", mixBlendMode: this.layoutDoc.tool === InkTool.Highlighter ? "multiply" : "unset" }}
                 onContextMenu={() => {
                     ContextMenu.Instance.addItem({
                         description: "Analyze Stroke",
@@ -60,7 +67,25 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
                         icon: "paint-brush"
                     });
                 }}
-            >
+            ><defs>
+                    <filter id="dangerShine">
+                        <feColorMatrix type="matrix"
+                            result="color"
+                            values="1 0 0 0 0
+                        0 0 0 0 0
+                        0 0 0 0 0
+                        0 0 0 1 0">
+                        </feColorMatrix>
+                        <feGaussianBlur in="color" stdDeviation="4" result="blur"></feGaussianBlur>
+                        <feOffset in="blur" dx="0" dy="0" result="offset"></feOffset>
+                        <feMerge>
+                            <feMergeNode in="bg"></feMergeNode>
+                            <feMergeNode in="offset"></feMergeNode>
+                            <feMergeNode in="SourceGraphic"></feMergeNode>
+                        </feMerge>
+                    </filter>
+                </defs>
+                {hpoints}
                 {points}
             </svg>
         );
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 97244ed06..b0461609a 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -1,7 +1,7 @@
 import { action, computed, observable } from "mobx";
 import { observer } from "mobx-react";
 import { Doc, Opt } from "../../../../fields/Doc";
-import { InkData, InkField } from "../../../../fields/InkField";
+import { InkData, InkField, InkTool } from "../../../../fields/InkField";
 import { List } from "../../../../fields/List";
 import { RichTextField } from "../../../../fields/RichTextField";
 import { SchemaHeaderField } from "../../../../fields/SchemaHeaderField";
@@ -271,10 +271,11 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
 
     @action
     onClick = (e: React.MouseEvent): void => {
-        if (
-            Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD &&
+        if (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD &&
             Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD) {
-            !(e.nativeEvent as any).formattedHandled && this.setPreviewCursor(e.clientX, e.clientY, false);
+            if (Doc.GetSelectedTool() === InkTool.None) {
+                !(e.nativeEvent as any).formattedHandled && this.setPreviewCursor(e.clientX, e.clientY, false);
+            }
             // let the DocumentView stopPropagation of this event when it selects this document
         } else {  // why do we get a click event when the cursor have moved a big distance?
             // let's cut it off here so no one else has to deal with it.
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 910aa744d..509f78021 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -14,6 +14,7 @@ import { List } from "../../../fields/List";
 import { numberRange } from "../../../Utils";
 import { ComputedField } from "../../../fields/ScriptField";
 import { listSpec } from "../../../fields/Schema";
+import { DocumentType } from "../../documents/DocumentTypes";
 
 export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
     dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, opacity?: number, highlight?: boolean, z: number, transition?: string } | undefined;
@@ -156,7 +157,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
                 zIndex: this.ZInd,
                 mixBlendMode: StrCast(this.layoutDoc.mixBlendMode) as any,
                 display: this.ZInd === -99 ? "none" : undefined,
-                pointerEvents: this.props.Document.isBackground || this.Opacity === 0 ? "none" : this.props.pointerEvents ? "all" : undefined
+                pointerEvents: this.props.Document.isBackground || this.Opacity === 0 || this.props.Document.type === DocumentType.INK ? "none" : this.props.pointerEvents ? "all" : undefined
             }} >
             {Doc.UserDoc().renderStyle !== "comic" ? (null) :
                 <div style={{ width: "100%", height: "100%", position: "absolute" }}>
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 98be1adc0..9f2b0124a 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1135,7 +1135,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             ["transparent", "#65350c", "#65350c", "yellow", "magenta", "cyan", "orange"] :
             ["transparent", "maroon", "maroon", "yellow", "magenta", "cyan", "orange"];
         const highlightStyles = ["solid", "dashed", "solid", "solid", "solid", "solid", "solid"];
-        let highlighting = fullDegree && this.layoutDoc.type !== DocumentType.FONTICON && this.layoutDoc._viewType !== CollectionViewType.Linear;
+        let highlighting = fullDegree && this.layoutDoc.type !== DocumentType.FONTICON && this.layoutDoc._viewType !== CollectionViewType.Linear && this.props.Document.type !== DocumentType.INK;
         highlighting = highlighting && this.props.focus !== emptyFunction;  // bcz: hack to turn off highlighting onsidebar panel documents.  need to flag a document as not highlightable in a more direct way
         return <div className={`documentView-node${this.topMost ? "-topmost" : ""}`}
             id={this.props.Document[Id]}
-- 
cgit v1.2.3-70-g09d2

