aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts8
-rw-r--r--src/client/views/GestureOverlay.tsx2
-rw-r--r--src/client/views/GlobalKeyHandler.ts2
-rw-r--r--src/client/views/InkControl.tsx101
-rw-r--r--src/client/views/InkControls.tsx118
-rw-r--r--src/client/views/InkHandles.tsx84
-rw-r--r--src/client/views/InkStroke.scss (renamed from src/client/views/InkingStroke.scss)2
-rw-r--r--src/client/views/InkStroke.tsx187
-rw-r--r--src/client/views/InkStrokeProperties.ts205
-rw-r--r--src/client/views/InkingStroke.tsx271
-rw-r--r--src/client/views/PropertiesButtons.tsx4
-rw-r--r--src/client/views/PropertiesView.tsx4
-rw-r--r--src/client/views/collections/CollectionMenu.tsx2
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx2
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx4
-rw-r--r--src/client/views/nodes/ColorBox.tsx2
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx4
-rw-r--r--src/client/views/nodes/DocumentView.tsx6
18 files changed, 468 insertions, 540 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 24682cbd0..188fe31c0 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -31,7 +31,7 @@ import { CollectionView, CollectionViewType } from "../views/collections/Collect
import { ContextMenu } from "../views/ContextMenu";
import { ContextMenuProps } from "../views/ContextMenuItem";
import { DFLT_IMAGE_NATIVE_DIM } from "../views/globalCssVariables.scss";
-import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, InkingStroke } from "../views/InkingStroke";
+import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, InkStroke } from "../views/InkStroke";
import { AudioBox } from "../views/nodes/AudioBox";
import { ColorBox } from "../views/nodes/ColorBox";
import { ComparisonBox } from "../views/nodes/ComparisonBox";
@@ -432,7 +432,7 @@ export namespace Docs {
options: { links: ComputedField.MakeFunction("links(self)") as any, hideLinkButton: true }
}],
[DocumentType.INK, {
- layout: { view: InkingStroke, dataField: defaultDataKey },
+ layout: { view: InkStroke, dataField: defaultDataKey },
options: { _fontFamily: "cursive", backgroundColor: "transparent", links: ComputedField.MakeFunction("links(self)") as any }
}],
[DocumentType.SCREENSHOT, {
@@ -760,7 +760,7 @@ export namespace Docs {
const I = new Doc();
I[Initializing] = true;
I.type = DocumentType.INK;
- I.layout = InkingStroke.LayoutString("data");
+ I.layout = InkStroke.LayoutString("data");
I.color = color;
I.fillColor = fillColor;
I.strokeWidth = Number(strokeWidth);
@@ -1144,7 +1144,7 @@ export namespace DocUtils {
layout = AudioBox.LayoutString;
} else if (field instanceof InkField) {
created = Docs.Create.InkDocument(ActiveInkColor(), CurrentUserUtils.SelectedTool, ActiveInkWidth(), ActiveInkBezierApprox(), ActiveFillColor(), ActiveArrowStart(), ActiveArrowEnd(), ActiveDash(), (field).inkData, resolved);
- layout = InkingStroke.LayoutString;
+ layout = InkStroke.LayoutString;
} else if (field instanceof List && field[0] instanceof Doc) {
created = Docs.Create.StackingDocument(DocListCast(field), resolved);
layout = CollectionView.LayoutString;
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 491bf18b2..455b3a935 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -17,7 +17,7 @@ import { Scripting } from "../util/Scripting";
import { Transform } from "../util/Transform";
import { CollectionFreeFormViewChrome } from "./collections/CollectionMenu";
import "./GestureOverlay.scss";
-import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, SetActiveArrowStart, SetActiveDash, SetActiveFillColor, SetActiveInkColor, SetActiveInkWidth } from "./InkingStroke";
+import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, SetActiveArrowStart, SetActiveDash, SetActiveFillColor, SetActiveInkColor, SetActiveInkWidth } from "./InkStroke";
import { DocumentView } from "./nodes/DocumentView";
import { RadialMenu } from "./nodes/RadialMenu";
import HorizontalPalette from "./Palette";
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index cbaa706e0..c1130ce61 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -116,7 +116,7 @@ export class KeyManager {
case "escape":
DocumentLinksButton.StartLink = undefined;
DocumentLinksButton.StartLinkView = undefined;
- InkStrokeProperties.Instance && (InkStrokeProperties.Instance._controlBtn = false);
+ InkStrokeProperties.Instance && (InkStrokeProperties.Instance._controlButton = false);
CurrentUserUtils.SelectedTool = InkTool.None;
var doDeselect = true;
if (SnappingManager.GetIsDragging()) {
diff --git a/src/client/views/InkControl.tsx b/src/client/views/InkControl.tsx
deleted file mode 100644
index accb16f61..000000000
--- a/src/client/views/InkControl.tsx
+++ /dev/null
@@ -1,101 +0,0 @@
-import React = require("react");
-import { observable, action } from "mobx";
-import { observer } from "mobx-react";
-import { InkStrokeProperties } from "./InkStrokeProperties";
-import { setupMoveUpEvents, emptyFunction } from "../../Utils";
-import { UndoManager } from "../util/UndoManager";
-import { ControlPoint } from "../../fields/InkField";
-import { Transform } from "../util/Transform";
-
-export interface InkControlProps {
- control: ControlPoint;
- left: number;
- top: number;
- scaleX: number;
- scaleY: number;
- strokeWidth: number;
- ScreenToLocalTransform: () => Transform;
-}
-
-@observer
-export class InkControl extends React.Component<InkControlProps> {
- @observable private _overControl = false;
-
- @action
- onPointerEnter = () => {
- this._overControl = true;
- }
-
- @action
- onPointerLeave = () => {
- this._overControl = false;
- }
-
- /**
- * Handles the movement of a selected control point when the user clicks and drags.
- * @param controlNum The index of the currently selected control point.
- */
- @action
- onControlDown = (e: React.PointerEvent, controlNum: number): void => {
- if (InkStrokeProperties.Instance) {
- InkStrokeProperties.Instance.moveControl(0, 0, 1);
- const controlUndo = UndoManager.StartBatch("DocDecs set radius");
- const screenScale = this.props.ScreenToLocalTransform().Scale;
- setupMoveUpEvents(this, e,
- (e: PointerEvent, down: number[], delta: number[]) => {
- InkStrokeProperties.Instance?.moveControl(-delta[0] * screenScale, -delta[1] * screenScale, controlNum);
- return false;
- },
- () => controlUndo?.end(), emptyFunction);
- }
- }
-
- /**
- * Deletes the currently selected point.
- */
- @action
- onDelete = (e: KeyboardEvent) => {
- if (["-", "Backspace", "Delete"].includes(e.key)) {
- if (InkStrokeProperties.Instance?.deletePoints()) e.stopPropagation();
- }
- }
-
- /**
- * Changes the current selected control point.
- */
- @action
- changeCurrPoint = (i: number) => {
- if (InkStrokeProperties.Instance) {
- InkStrokeProperties.Instance._currPoint = i;
- document.addEventListener("keydown", this.onDelete, true);
- }
- }
-
-
- render() {
- const control = this.props.control;
- const left = this.props.left;
- const top = this.props.top;
- const scaleX = this.props.scaleX;
- const scaleY = this.props.scaleY;
- const strokeWidth = this.props.strokeWidth;
-
- return (
- <svg height="10" width="10" key={`ctrl${control.I}`}>
- <rect
- x={(control.X - left - strokeWidth / 2) * scaleX}
- y={(control.Y - top - strokeWidth / 2) * scaleY}
- height={this._overControl ? strokeWidth * 1.5 : strokeWidth}
- width={this._overControl ? strokeWidth * 1.5 : strokeWidth}
- strokeWidth={strokeWidth / 6} stroke="#1F85DE"
- fill={InkStrokeProperties.Instance?._currPoint === control.I ? "#1F85DE" : "white"}
- onPointerDown={(e) => { this.changeCurrPoint(control.I); this.onControlDown(e, control.I); }}
- onMouseEnter={this.onPointerEnter}
- onMouseLeave={this.onPointerLeave}
- pointerEvents="all"
- cursor="default"
- />
- </svg>
- )
- }
-} \ No newline at end of file
diff --git a/src/client/views/InkControls.tsx b/src/client/views/InkControls.tsx
new file mode 100644
index 000000000..eeddfce4c
--- /dev/null
+++ b/src/client/views/InkControls.tsx
@@ -0,0 +1,118 @@
+import React = require("react");
+import { observable, action } from "mobx";
+import { observer } from "mobx-react";
+import { InkStrokeProperties } from "./InkStrokeProperties";
+import { setupMoveUpEvents, emptyFunction } from "../../Utils";
+import { UndoManager } from "../util/UndoManager";
+import { ControlPoint, InkData, PointData } from "../../fields/InkField";
+import { Transform } from "../util/Transform";
+
+export interface InkControlProps {
+ data: InkData;
+ addedPoints: PointData[];
+ format: number[];
+ ScreenToLocalTransform: () => Transform;
+}
+
+@observer
+export class InkControls extends React.Component<InkControlProps> {
+ // @observable private _controlPoints: ControlPoint[] = [];
+ @observable private _overControl = -1;
+ @observable private _overAddPoint = -1;
+
+ /**
+ * Handles the movement of a selected control point when the user clicks and drags.
+ * @param controlNum The index of the currently selected control point.
+ */
+ @action
+ onControlDown = (e: React.PointerEvent, controlNum: number): void => {
+ if (InkStrokeProperties.Instance) {
+ InkStrokeProperties.Instance.moveControl(0, 0, 1);
+ const controlUndo = UndoManager.StartBatch("DocDecs set radius");
+ const screenScale = this.props.ScreenToLocalTransform().Scale;
+ setupMoveUpEvents(this, e,
+ (e: PointerEvent, down: number[], delta: number[]) => {
+ InkStrokeProperties.Instance?.moveControl(-delta[0] * screenScale, -delta[1] * screenScale, controlNum);
+ return false;
+ },
+ () => controlUndo?.end(), emptyFunction);
+ }
+ }
+
+ /**
+ * Deletes the currently selected point.
+ */
+ @action
+ onDelete = (e: KeyboardEvent) => {
+ if (["-", "Backspace", "Delete"].includes(e.key)) {
+ if (InkStrokeProperties.Instance?.deletePoints()) e.stopPropagation();
+ }
+ }
+
+ /**
+ * Changes the current selected control point.
+ */
+ @action
+ changeCurrPoint = (i: number) => {
+ if (InkStrokeProperties.Instance) {
+ InkStrokeProperties.Instance._currentPoint = i;
+ document.addEventListener("keydown", this.onDelete, true);
+ }
+ }
+
+ @action onEnterControl = (i: number) => { this._overControl = i; };
+ @action onLeaveControl = () => { this._overControl = -1; };
+ @action onEnterAddPoint = (i: number) => { this._overAddPoint = i; };
+ @action onLeaveAddPoint = () => { this._overAddPoint = -1; };
+
+ render() {
+ const data = this.props.data;
+ const controlPoints: ControlPoint[] = [];
+ if (data.length >= 4) {
+ for (let i = 0; i <= data.length - 4; i += 4) {
+ controlPoints.push({ X: data[i].X, Y: data[i].Y, I: i });
+ controlPoints.push({ X: data[i + 3].X, Y: data[i + 3].Y, I: i + 3 });
+ }
+ }
+ const addedPoints = this.props.addedPoints;
+ const [left, top, scaleX, scaleY, strokeWidth, dotsize] = this.props.format;
+
+ return (
+ <>
+ {addedPoints.map((pts, i) =>
+ <svg height="10" width="10" key={`add${i}`}>
+ <circle
+ cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2}
+ cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2}
+ r={strokeWidth / 2}
+ stroke={this._overAddPoint === i ? "#1F85DE" : "transparent"}
+ strokeWidth={dotsize / 4} fill={this._overAddPoint === i ? "#1F85DE" : "transparent"}
+ onPointerDown={() => { InkStrokeProperties.Instance?.addPoints(pts.X, pts.Y, addedPoints, i, controlPoints); }}
+ onMouseEnter={() => this.onEnterAddPoint(i)}
+ onMouseLeave={this.onLeaveAddPoint}
+ pointerEvents="all"
+ cursor="all-scroll"
+ />
+ </svg>
+ )}
+ {controlPoints.map((control, i) =>
+ <svg height="10" width="10" key={`ctrl${i}`}>
+ <rect
+ x={(control.X - left - strokeWidth / 2) * scaleX}
+ y={(control.Y - top - strokeWidth / 2) * scaleY}
+ height={this._overControl === i ? strokeWidth * 1.5 : strokeWidth}
+ width={this._overControl === i ? strokeWidth * 1.5 : strokeWidth}
+ strokeWidth={strokeWidth / 6} stroke="#1F85DE"
+ fill={InkStrokeProperties.Instance?._currentPoint === control.I ? "#1F85DE" : "white"}
+ onPointerDown={(e) => { this.changeCurrPoint(control.I); this.onControlDown(e, control.I); }}
+ onMouseEnter={() => this.onEnterControl(i)}
+ onMouseLeave={this.onLeaveControl}
+ pointerEvents="all"
+ cursor="default"
+ />
+ </svg>
+ )}
+ </>
+ );
+ }
+} \ No newline at end of file
diff --git a/src/client/views/InkHandles.tsx b/src/client/views/InkHandles.tsx
new file mode 100644
index 000000000..c2163c124
--- /dev/null
+++ b/src/client/views/InkHandles.tsx
@@ -0,0 +1,84 @@
+import React = require("react");
+import { observable, action } from "mobx";
+import { observer } from "mobx-react";
+import { InkStrokeProperties } from "./InkStrokeProperties";
+import { setupMoveUpEvents, emptyFunction } from "../../Utils";
+import { UndoManager } from "../util/UndoManager";
+import { InkData, HandlePoint, HandleLine } from "../../fields/InkField";
+import { Transform } from "../util/Transform";
+
+export interface InkControlProps {
+ data: InkData;
+ format: number[];
+ ScreenToLocalTransform: () => Transform;
+}
+
+@observer
+export class InkHandles extends React.Component<InkControlProps> {
+ /**
+ * Handles the movement of a selected handle point when the user clicks and drags.
+ * @param handleNum The index of the currently selected handle point.
+ */
+ onHandleDown = (e: React.PointerEvent, handleNum: number): void => {
+ if (InkStrokeProperties.Instance) {
+ InkStrokeProperties.Instance.moveControl(0, 0, 1);
+ const controlUndo = UndoManager.StartBatch("DocDecs set radius");
+ const screenScale = this.props.ScreenToLocalTransform().Scale;
+ setupMoveUpEvents(this, e, (e: PointerEvent, down: number[], delta: number[]) => {
+ InkStrokeProperties.Instance?.moveHandle(-delta[0] * screenScale, -delta[1] * screenScale, handleNum);
+ return false;
+ }, () => controlUndo?.end(), emptyFunction
+ );
+ }
+ }
+
+ render() {
+ const formatInstance = InkStrokeProperties.Instance;
+ if (!formatInstance) return (null);
+ const data = this.props.data;
+ const handlePoints: HandlePoint[] = [];
+ const handleLines: HandleLine[] = [];
+ if (data.length >= 4) {
+ // adding first and last (single) handle lines
+ handleLines.push({ X1: data[0].X, Y1: data[0].Y, X2: data[1].X, Y2: data[1].Y, dot1: 0, dot2: 0 });
+ handleLines.push({ X1: data[data.length - 2].X, Y1: data[data.length - 2].Y, X2: data[data.length - 1].X, Y2: data[data.length - 1].Y, dot1: data.length - 1, dot2: data.length - 1 });
+ for (let i = 0; i <= data.length - 4; i += 4) {
+ handlePoints.push({ X: data[i + 1].X, Y: data[i + 1].Y, I: i + 1, dot1: i, dot2: i === 0 ? i : i - 1 });
+ handlePoints.push({ X: data[i + 2].X, Y: data[i + 2].Y, I: i + 2, dot1: i + 3, dot2: i === data.length ? i + 3 : i + 4 });
+ }
+ for (let i = 2; i < data.length - 4; i += 4) {
+ handleLines.push({ X1: data[i].X, Y1: data[i].Y, X2: data[i + 3].X, Y2: data[i + 3].Y, dot1: i + 1, dot2: i + 2 });
+ }
+ }
+ const [left, top, scaleX, scaleY, strokeWidth, dotsize] = this.props.format;
+
+ return (
+ <>
+ {handlePoints.map((pts, i) =>
+ <svg height="10" width="10" key={`hdl${i}`}>
+ <circle
+ cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2}
+ cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2}
+ r={strokeWidth / 2}
+ strokeWidth={0}
+ fill="#1F85DE"
+ onPointerDown={(e) => this.onHandleDown(e, pts.I)}
+ pointerEvents="all"
+ cursor="default"
+ display={(pts.dot1 === formatInstance._currentPoint || pts.dot2 === formatInstance._currentPoint) ? "inherit" : "none"} />
+ </svg>)}
+ {handleLines.map((pts, i) =>
+ <svg height="100" width="100" key={`line${i}`}>
+ <line
+ x1={(pts.X1 - left - strokeWidth / 2) * scaleX + strokeWidth / 2}
+ y1={(pts.Y1 - top - strokeWidth / 2) * scaleY + strokeWidth / 2}
+ x2={(pts.X2 - left - strokeWidth / 2) * scaleX + strokeWidth / 2}
+ y2={(pts.Y2 - top - strokeWidth / 2) * scaleY + strokeWidth / 2}
+ stroke="#1F85DE"
+ strokeWidth={dotsize / 8}
+ display={(pts.dot1 === formatInstance._currentPoint || pts.dot2 === formatInstance._currentPoint) ? "inherit" : "none"} />
+ </svg>)}
+ </>
+ );
+ }
+} \ No newline at end of file
diff --git a/src/client/views/InkingStroke.scss b/src/client/views/InkStroke.scss
index f67b1779d..812a79bd5 100644
--- a/src/client/views/InkingStroke.scss
+++ b/src/client/views/InkStroke.scss
@@ -1,4 +1,4 @@
-.inkingStroke {
+.inkStroke {
mix-blend-mode: multiply;
stroke-linejoin: round;
stroke-linecap: round;
diff --git a/src/client/views/InkStroke.tsx b/src/client/views/InkStroke.tsx
new file mode 100644
index 000000000..9ca8bdbea
--- /dev/null
+++ b/src/client/views/InkStroke.tsx
@@ -0,0 +1,187 @@
+import React = require("react");
+import { action, observable } from "mobx";
+import { observer } from "mobx-react";
+import { Doc } from "../../fields/Doc";
+import { documentSchema } from "../../fields/documentSchemas";
+import { InkData, InkField, InkTool, ControlPoint, HandlePoint, HandleLine } from "../../fields/InkField";
+import { makeInterface } from "../../fields/Schema";
+import { Cast, StrCast } from "../../fields/Types";
+import { TraceMobx } from "../../fields/util";
+import { setupMoveUpEvents, emptyFunction, returnFalse } from "../../Utils";
+import { CognitiveServices } from "../cognitive_services/CognitiveServices";
+import { InteractionUtils } from "../util/InteractionUtils";
+import { Scripting } from "../util/Scripting";
+import { UndoManager } from "../util/UndoManager";
+import { ContextMenu } from "./ContextMenu";
+import { ViewBoxBaseComponent } from "./DocComponent";
+import "./InkStroke.scss";
+import { FieldView, FieldViewProps } from "./nodes/FieldView";
+import { InkStrokeProperties } from "./InkStrokeProperties";
+import { CurrentUserUtils } from "../util/CurrentUserUtils";
+import { InkControls } from "./InkControls";
+import { InkHandles } from "./InkHandles";
+
+type InkDocument = makeInterface<[typeof documentSchema]>;
+const InkDocument = makeInterface(documentSchema);
+
+@observer
+export class InkStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocument>(InkDocument) {
+ static readonly MaskDim = 50000;
+ @observable private _properties?: InkStrokeProperties;
+
+ constructor(props: FieldViewProps & InkDocument) {
+ super(props);
+
+ this._properties = InkStrokeProperties.Instance;
+ }
+
+ public static LayoutString(fieldStr: string) {
+ return FieldView.LayoutString(InkStroke, fieldStr);
+ }
+
+ analyzeStrokes() {
+ const data: InkData = Cast(this.dataDoc[this.fieldKey], InkField)?.inkData ?? [];
+ CognitiveServices.Inking.Appliers.ConcatenateHandwriting(this.dataDoc, ["inkAnalysis", "handwriting"], [data]);
+ }
+
+ @action
+ public static toggleMask = (inkDoc: Doc) => {
+ inkDoc.isInkMask = !inkDoc.isInkMask;
+ inkDoc._backgroundColor = inkDoc.isInkMask ? "rgba(0,0,0,0.7)" : undefined;
+ inkDoc.mixBlendMode = inkDoc.isInkMask ? "hard-light" : undefined;
+ inkDoc.color = "#9b9b9bff";
+ inkDoc._stayInCollection = inkDoc.isInkMask ? true : undefined;
+ }
+
+ /**
+ * Handles the movement of the entire ink object when the user clicks and drags.
+ * @param e React Pointer Event.
+ */
+ onPointerDown = (e: React.PointerEvent) => {
+ if (this.props.isSelected(true)) {
+ setupMoveUpEvents(this, e, returnFalse, emptyFunction,
+ action((e: PointerEvent, doubleTap: boolean | undefined) =>
+ doubleTap && this._properties && (this._properties._controlButton = true))
+ );
+ }
+ }
+
+ render() {
+ TraceMobx();
+
+ const data: InkData = Cast(this.dataDoc[this.fieldKey], InkField)?.inkData ?? [];
+ const strokeWidth = Number(this.layoutDoc.strokeWidth);
+ const lineTop = Math.min(...data.map(p => p.Y));
+ const lineBottom = Math.max(...data.map(p => p.Y));
+ const lineLeft = Math.min(...data.map(p => p.X));
+ const lineRight = Math.max(...data.map(p => p.X));
+ const left = lineLeft - strokeWidth / 2;
+ const top = lineTop - strokeWidth / 2;
+ const right = lineRight + strokeWidth / 2;
+ const bottom = lineBottom + strokeWidth / 2;
+ const width = Math.max(1, right - left);
+ const height = Math.max(1, bottom - top);
+ const scaleX = width === strokeWidth ? 1 : (this.props.PanelWidth() - strokeWidth) / (width - strokeWidth);
+ const scaleY = height === strokeWidth ? 1 : (this.props.PanelHeight() - strokeWidth) / (height - strokeWidth);
+ const strokeColor = StrCast(this.layoutDoc.color, "");
+ const dotsize = Math.max(width * scaleX, height * scaleY) / 40;
+
+ // Visually renders the polygonal line made by the user.
+ const inkLine = InteractionUtils.CreatePolyline(data, left, top, strokeColor, strokeWidth, strokeWidth,
+ StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "none"),
+ StrCast(this.layoutDoc.strokeStartMarker), StrCast(this.layoutDoc.strokeEndMarker),
+ StrCast(this.layoutDoc.strokeDash), scaleX, scaleY, "", "none",
+ this.props.isSelected() && strokeWidth <= 5 && lineBottom - lineTop > 1 && lineRight - lineLeft > 1,
+ false);
+ const selectedLine = InteractionUtils.CreatePolyline(
+ data, lineLeft - strokeWidth * 3, lineTop - strokeWidth * 3, "#1F85DE", strokeWidth / 6,
+ strokeWidth / 6,StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "none"),
+ StrCast(this.layoutDoc.strokeStartMarker), StrCast(this.layoutDoc.strokeEndMarker),
+ StrCast(this.layoutDoc.strokeDash), scaleX, scaleY, "", "none",
+ this.props.isSelected() && strokeWidth <= 5 && lineBottom - lineTop > 1 && lineRight - lineLeft > 1,
+ false);
+ // Invisible polygonal line that enables the ink to be selected by the user.
+ const clickableLine = InteractionUtils.CreatePolyline(data, left, top,
+ this.props.isSelected() && strokeWidth > 5 ? strokeColor : "transparent", strokeWidth,
+ strokeWidth + 15, StrCast(this.layoutDoc.strokeBezier),
+ StrCast(this.layoutDoc.fillColor, "none"), "none", "none", undefined, scaleX, scaleY, "",
+ this.props.layerProvider?.(this.props.Document) === false ? "none" : "visiblepainted", false, true);
+ const addedPoints = InteractionUtils.CreatePoints(data, left, top, strokeColor, strokeWidth, strokeWidth,
+ StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "none"),
+ StrCast(this.layoutDoc.strokeStartMarker), StrCast(this.layoutDoc.strokeEndMarker),
+ StrCast(this.layoutDoc.strokeDash), scaleX, scaleY, "", "none",
+ this.props.isSelected() && strokeWidth <= 5, false);
+
+ return (
+ <svg className="inkStroke"
+ style={{
+ pointerEvents: this.props.Document.isInkMask && this.props.layerProvider?.(this.props.Document) !== false ? "all" : "none",
+ transform: this.props.Document.isInkMask ? `translate(${InkStroke.MaskDim / 2}px, ${InkStroke.MaskDim / 2}px)` : undefined,
+ mixBlendMode: this.layoutDoc.tool === InkTool.Highlighter ? "multiply" : "unset",
+ overflow: "visible",
+ }}
+ onPointerDown={this.onPointerDown}
+ onContextMenu={() => {
+ const cm = ContextMenu.Instance;
+ if (cm) {
+ !Doc.UserDoc().noviceMode && cm.addItem({ description: "Recognize Writing", event: this.analyzeStrokes, icon: "paint-brush" });
+ cm.addItem({ description: "Toggle Mask", event: () => InkStroke.toggleMask(this.rootDoc), icon: "paint-brush" });
+ cm.addItem({ description: "Edit Points", event: action(() => {if (this._properties) { this._properties._controlButton = !this._properties._controlButton; }} ), icon: "paint-brush" });
+ }
+ }}
+ >
+
+ {clickableLine}
+ {inkLine}
+ {this.props.isSelected() ? selectedLine : ""}
+ {this.props.isSelected() && this._properties?._controlButton ?
+ <>
+ <InkControls
+ data={data}
+ addedPoints={addedPoints}
+ format={[left, top, scaleX, scaleY, strokeWidth, dotsize]}
+ ScreenToLocalTransform={this.props.ScreenToLocalTransform} />
+ <InkHandles
+ data={data}
+ format={[left, top, scaleX, scaleY, strokeWidth, dotsize]}
+ ScreenToLocalTransform={this.props.ScreenToLocalTransform} />
+ </> : ""}
+ </svg>
+ );
+ }
+}
+
+
+export function SetActiveInkWidth(width: string): void { !isNaN(parseInt(width)) && ActiveInkPen() && (ActiveInkPen().activeInkWidth = width); }
+export function SetActiveBezierApprox(bezier: string): void { ActiveInkPen() && (ActiveInkPen().activeInkBezier = isNaN(parseInt(bezier)) ? "" : bezier); }
+export function SetActiveInkColor(value: string) { ActiveInkPen() && (ActiveInkPen().activeInkColor = value); }
+export function SetActiveFillColor(value: string) { ActiveInkPen() && (ActiveInkPen().activeFillColor = value); }
+export function SetActiveArrowStart(value: string) { ActiveInkPen() && (ActiveInkPen().activeArrowStart = value); }
+export function SetActiveArrowEnd(value: string) { ActiveInkPen() && (ActiveInkPen().activeArrowEnd = value); }
+export function SetActiveDash(dash: string): void { !isNaN(parseInt(dash)) && ActiveInkPen() && (ActiveInkPen().activeDash = dash); }
+export function ActiveInkPen(): Doc { return Doc.UserDoc(); }
+export function ActiveInkColor(): string { return StrCast(ActiveInkPen()?.activeInkColor, "black"); }
+export function ActiveFillColor(): string { return StrCast(ActiveInkPen()?.activeFillColor, ""); }
+export function ActiveArrowStart(): string { return StrCast(ActiveInkPen()?.activeArrowStart, ""); }
+export function ActiveArrowEnd(): string { return StrCast(ActiveInkPen()?.activeArrowEnd, ""); }
+export function ActiveDash(): string { return StrCast(ActiveInkPen()?.activeDash, "0"); }
+export function ActiveInkWidth(): string { return StrCast(ActiveInkPen()?.activeInkWidth, "1"); }
+export function ActiveInkBezierApprox(): string { return StrCast(ActiveInkPen()?.activeInkBezier); }
+Scripting.addGlobal(function activateBrush(pen: any, width: any, color: any, fill: any, arrowStart: any, arrowEnd: any, dash: any) {
+ CurrentUserUtils.SelectedTool = pen ? InkTool.Highlighter : InkTool.None;
+ SetActiveInkWidth(width);
+ SetActiveInkColor(color);
+ SetActiveFillColor(fill);
+ SetActiveArrowStart(arrowStart);
+ SetActiveArrowEnd(arrowEnd);
+ SetActiveDash(dash);
+});
+Scripting.addGlobal(function activateEraser(pen: any) { return CurrentUserUtils.SelectedTool = pen ? InkTool.Eraser : InkTool.None; });
+Scripting.addGlobal(function activateStamp(pen: any) { return CurrentUserUtils.SelectedTool = pen ? InkTool.Stamp : InkTool.None; });
+Scripting.addGlobal(function deactivateInk() { return CurrentUserUtils.SelectedTool = InkTool.None; });
+Scripting.addGlobal(function setInkWidth(width: any) { return SetActiveInkWidth(width); });
+Scripting.addGlobal(function setInkColor(color: any) { return SetActiveInkColor(color); });
+Scripting.addGlobal(function setFillColor(fill: any) { return SetActiveFillColor(fill); });
+Scripting.addGlobal(function setActiveArrowStart(arrowStart: any) { return SetActiveArrowStart(arrowStart); });
+Scripting.addGlobal(function setActiveArrowEnd(arrowEnd: any) { return SetActiveArrowStart(arrowEnd); });
+Scripting.addGlobal(function setActiveDash(dash: any) { return SetActiveDash(dash); });
diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts
index 720a89334..a5c028730 100644
--- a/src/client/views/InkStrokeProperties.ts
+++ b/src/client/views/InkStrokeProperties.ts
@@ -1,5 +1,4 @@
import { action, computed, observable } from "mobx";
-import { ColorState } from 'react-color';
import { Doc, Field, Opt } from "../../fields/Doc";
import { Document } from "../../fields/documentSchemas";
import { InkField, InkData, PointData } from "../../fields/InkField";
@@ -11,80 +10,62 @@ import { undoBatch } from "../util/UndoManager";
export class InkStrokeProperties {
static Instance: InkStrokeProperties | undefined;
- private _lastFill = "#D0021B";
- private _lastLine = "#D0021B";
- private _lastDash = "2";
-
@observable _lock = false;
- @observable _controlBtn = false;
- @observable _currPoint = -1;
+ @observable _controlButton = false;
+ @observable _currentPoint = -1;
constructor() {
InkStrokeProperties.Instance = this;
}
+ @computed get selectedInk() {
+ const inks = SelectionManager.Views().filter(i => Document(i.rootDoc).type === DocumentType.INK);
+ return inks.length ? inks : undefined;
+ }
+
getField(key: string) {
return this.selectedInk?.reduce((p, i) =>
(p === undefined || (p && p === i.rootDoc[key])) && i.rootDoc[key] !== "0" ? Field.toString(i.rootDoc[key] as Field) : "", undefined as Opt<string>);
}
- @computed get selectedInk() {
- const inks = SelectionManager.Views().filter(i => Document(i.rootDoc).type === DocumentType.INK);
- return inks.length ? inks : undefined;
+ /**
+ * Helper function that enables other functions to be applied to a particular ink instance.
+ * @param func The inputted function.
+ * @param requireCurrPoint Indicates whether the current selected point is needed.
+ */
+ applyFunction = (func: (doc: Doc, ink: InkData, ptsXscale: number, ptsYscale: number) => { X: number, Y: number }[] | undefined, requireCurrPoint: boolean = false) => {
+ var appliedFunc = false;
+ this.selectedInk?.forEach(action(inkView => {
+ if (this.selectedInk?.length === 1 && (!requireCurrPoint || this._currentPoint !== -1)) {
+ const doc = Document(inkView.rootDoc);
+ if (doc.type === DocumentType.INK && doc.width && doc.height) {
+ const ink = Cast(doc.data, InkField)?.inkData;
+ if (ink) {
+ const oldXrange = (xs => ({ coord: NumCast(doc.x), min: Math.min(...xs), max: Math.max(...xs) }))(ink.map(p => p.X));
+ const oldYrange = (ys => ({ coord: NumCast(doc.y), min: Math.min(...ys), max: Math.max(...ys) }))(ink.map(p => p.Y));
+ const ptsXscale = NumCast(doc._width) / (oldXrange.max - oldXrange.min);
+ const ptsYscale = NumCast(doc._height) / (oldYrange.max - oldYrange.min);
+ const newPoints = func(doc, ink, ptsXscale, ptsYscale);
+ if (newPoints) {
+ const newXrange = (xs => ({ min: Math.min(...xs), max: Math.max(...xs) }))(newPoints.map(p => p.X));
+ const newYrange = (ys => ({ min: Math.min(...ys), max: Math.max(...ys) }))(newPoints.map(p => p.Y));
+ doc._width = (newXrange.max - newXrange.min) * ptsXscale;
+ doc._height = (newYrange.max - newYrange.min) * ptsYscale;
+ doc.x = (oldXrange.coord + (newXrange.min - oldXrange.min) * ptsXscale);
+ doc.y = (oldYrange.coord + (newYrange.min - oldYrange.min) * ptsYscale);
+ Doc.GetProto(doc).data = new InkField(newPoints);
+ appliedFunc = true;
+ }
+ }
+ }
+ }
+ }));
+ return appliedFunc;
}
- // @computed get unFilled() { return this.selectedInk?.reduce((p, i) => p && !i.rootDoc.fillColor ? true : false, true) || false; }
- // @computed get unStrokd() { return this.selectedInk?.reduce((p, i) => p && !i.rootDoc.color ? true : false, true) || false; }
- // @computed get solidFil() { return this.selectedInk?.reduce((p, i) => p && i.rootDoc.fillColor ? true : false, true) || false; }
- // @computed get solidStk() { return this.selectedInk?.reduce((p, i) => p && i.rootDoc.color && (!i.rootDoc.strokeDash || i.rootDoc.strokeDash === "0") ? true : false, true) || false; }
- // @computed get dashdStk() { return !this.unStrokd && this.getField("strokeDash") || ""; }
- // @computed get colorFil() { const ccol = this.getField("fillColor") || ""; ccol && (this._lastFill = ccol); return ccol; }
- // @computed get colorStk() { const ccol = this.getField("color") || ""; ccol && (this._lastLine = ccol); return ccol; }
- // @computed get widthStk() { return this.getField("strokeWidth") || "1"; }
- // @computed get markHead() { return this.getField("strokeStartMarker") || ""; }
- // @computed get markTail() { return this.getField("strokeEndMarker") || ""; }
- // @computed get shapeHgt() { return this.getField("_height"); }
- // @computed get shapeWid() { return this.getField("_width"); }
- // @computed get shapeXps() { return this.getField("x"); }
- // @computed get shapeYps() { return this.getField("y"); }
- // @computed get shapeRot() { return this.getField("rotation"); }
- // set unFilled(value) { this.colorFil = value ? "" : this._lastFill; }
- // set solidFil(value) { this.unFilled = !value; }
- // set colorFil(value) { value && (this._lastFill = value); this.selectedInk?.forEach(i => i.rootDoc.fillColor = value ? value : undefined); }
- // set colorStk(value) { value && (this._lastLine = value); this.selectedInk?.forEach(i => i.rootDoc.color = value ? value : undefined); }
- // set markHead(value) { this.selectedInk?.forEach(i => i.rootDoc.strokeStartMarker = value); }
- // set markTail(value) { this.selectedInk?.forEach(i => i.rootDoc.strokeEndMarker = value); }
- // set unStrokd(value) { this.colorStk = value ? "" : this._lastLine; }
- // set solidStk(value) { this.dashdStk = ""; this.unStrokd = !value; }
- // set dashdStk(value) {
- // value && (this._lastDash = value) && (this.unStrokd = false);
- // this.selectedInk?.forEach(i => i.rootDoc.strokeDash = value ? this._lastDash : undefined);
- // }
- // set shapeXps(value) { this.selectedInk?.forEach(i => i.rootDoc.x = Number(value)); }
- // set shapeYps(value) { this.selectedInk?.forEach(i => i.rootDoc.y = Number(value)); }
- // set shapeRot(value) { this.selectedInk?.forEach(i => i.rootDoc.rotation = Number(value)); }
- // set widthStk(value) { this.selectedInk?.forEach(i => i.rootDoc.strokeWidth = Number(value)); }
- // set shapeWid(value) {
- // this.selectedInk?.filter(i => i.rootDoc._width && i.rootDoc._height).forEach(i => {
- // const oldWidth = NumCast(i.rootDoc._width);
- // i.rootDoc._width = Number(value);
- // this._lock && (i.rootDoc._height = (i.rootDoc._width * NumCast(i.rootDoc._height)) / oldWidth);
- // });
- // }
- // set shapeHgt(value) {
- // this.selectedInk?.filter(i => i.rootDoc._width && i.rootDoc._height).forEach(i => {
- // const oldHeight = NumCast(i.rootDoc._height);
- // i.rootDoc._height = Number(value);
- // this._lock && (i.rootDoc._width = (i.rootDoc._height * NumCast(i.rootDoc._width)) / oldHeight);
- // });
- // }
-
/**
* Adds a new control point to the ink instance when editing its format.
- * @param x The x-coordinate of the current new point.
- * @param y The y-coordinate of the current new point.
- * @param pts The list containing all of the points to be added in PointData form.
- * @param index The index of the current new point.
+ * @param index The index of the new point.
* @param control The list of all control points of the ink.
*/
@undoBatch
@@ -114,7 +95,7 @@ export class InkStrokeProperties {
for (var i = spNum; i < ink.length; i++) {
newPoints.push({ X: ink[i].X, Y: ink[i].Y });
}
- this._currPoint = -1;
+ this._currentPoint = -1;
Doc.GetProto(doc).data = new InkField(newPoints);
}
}
@@ -123,56 +104,20 @@ export class InkStrokeProperties {
}
/**
- * Helper function that enables other functions to be applied to a particular ink instance.
- * @param func The inputted function.
- * @param requireCurrPoint Indicates whether the current selected point is needed.
- * @returns The applied function.
- */
- applyFunction = (func: (doc: Doc, ink: InkData, ptsXscale: number, ptsYscale: number) => { X: number, Y: number }[] | undefined, requireCurrPoint: boolean = false) => {
- var appliedFunc = false;
- this.selectedInk?.forEach(action(inkView => {
- if (this.selectedInk?.length === 1 && (!requireCurrPoint || this._currPoint !== -1)) {
- const doc = Document(inkView.rootDoc);
- if (doc.type === DocumentType.INK && doc.width && doc.height) {
- const ink = Cast(doc.data, InkField)?.inkData;
- if (ink) {
- const oldXrange = (xs => ({ coord: NumCast(doc.x), min: Math.min(...xs), max: Math.max(...xs) }))(ink.map(p => p.X));
- const oldYrange = (ys => ({ coord: NumCast(doc.y), min: Math.min(...ys), max: Math.max(...ys) }))(ink.map(p => p.Y));
- const ptsXscale = NumCast(doc._width) / (oldXrange.max - oldXrange.min);
- const ptsYscale = NumCast(doc._height) / (oldYrange.max - oldYrange.min);
- const newPoints = func(doc, ink, ptsXscale, ptsYscale);
- if (newPoints) {
- const newXrange = (xs => ({ min: Math.min(...xs), max: Math.max(...xs) }))(newPoints.map(p => p.X));
- const newYrange = (ys => ({ min: Math.min(...ys), max: Math.max(...ys) }))(newPoints.map(p => p.Y));
- doc._width = (newXrange.max - newXrange.min) * ptsXscale;
- doc._height = (newYrange.max - newYrange.min) * ptsYscale;
- doc.x = (oldXrange.coord + (newXrange.min - oldXrange.min) * ptsXscale);
- doc.y = (oldYrange.coord + (newYrange.min - oldYrange.min) * ptsYscale);
- Doc.GetProto(doc).data = new InkField(newPoints);
- appliedFunc = true;
- }
- }
- }
- }
- }));
- return appliedFunc;
- }
-
- /**
* Deletes the points of the current ink instance.
* @returns The changed x- and y-coordinates of the control points.
*/
@undoBatch
@action
deletePoints = () => this.applyFunction((doc: Doc, ink: InkData) => {
- var newPoints: { X: number, Y: number }[] = [];
- const toRemove = Math.floor(((this._currPoint + 2) / 4));
- for (var i = 0; i < ink.length; i++) {
+ const newPoints: { X: number, Y: number }[] = [];
+ const toRemove = Math.floor(((this._currentPoint + 2) / 4));
+ for (let i = 0; i < ink.length; i++) {
if (Math.floor((i + 2) / 4) !== toRemove && (toRemove !== 0 || i > 3)) {
newPoints.push({ X: ink[i].X, Y: ink[i].Y });
}
}
- this._currPoint = -1;
+ this._currentPoint = -1;
if (newPoints.length < 4) return undefined;
if (newPoints.length === 4) {
const newerPoints: { X: number, Y: number }[] = [];
@@ -183,7 +128,7 @@ export class InkStrokeProperties {
return newerPoints;
}
return newPoints;
- }, true);
+ }, true)
/**
* Rotates the points of the current ink instance by a certain angle degree.
@@ -193,7 +138,7 @@ export class InkStrokeProperties {
@undoBatch
@action
rotateInk = (angle: number) => {
- this.applyFunction((doc: Doc, ink: InkData, ptsXscale: number, ptsYscale: number) => {
+ this.applyFunction((doc: Doc, ink: InkData, xScale: number, yScale: number) => {
const oldXrange = (xs => ({ coord: NumCast(doc.x), min: Math.min(...xs), max: Math.max(...xs) }))(ink.map(p => p.X));
const oldYrange = (ys => ({ coord: NumCast(doc.y), min: Math.min(...ys), max: Math.max(...ys) }))(ink.map(p => p.Y));
const centerPoint = { X: (oldXrange.min + oldXrange.max) / 2, Y: (oldYrange.min + oldYrange.max) / 2 };
@@ -234,7 +179,7 @@ export class InkStrokeProperties {
}
}
return newPoints;
- });
+ })
/**
* Rotates the target point about the origin point for a given angle (radians).
@@ -247,7 +192,7 @@ export class InkStrokeProperties {
const newY = Math.sin(angle) * target.X + Math.cos(angle) * target.Y;
target.X = newX + origin.X;
target.Y = newY + origin.Y;
- return target
+ return target;
}
/**
@@ -277,54 +222,20 @@ export class InkStrokeProperties {
@action
moveHandle = (deltaX: number, deltaY: number, handleIndex: number) =>
this.applyFunction((doc: Doc, ink: InkData, xScale: number, yScale: number) => {
- const newPoints: { X: number, Y: number }[] = [];
const order = handleIndex % 4;
- let newHandlePoint = { X: 0, Y: 0 };
-
- for (var i = 0; i < ink.length; i++) {
- if (handleIndex === i) {
- newHandlePoint = { X: ink[i].X - deltaX / xScale, Y: ink[i].Y - deltaY / yScale };
- newPoints.push({ X: newHandlePoint.X, Y: newHandlePoint.Y });
- } else {
- newPoints.push({ X: ink[i].X, Y: ink[i].Y });
- }
- }
-
+ const oldHandlePoint = ink[handleIndex];
+ const newHandlePoint = { X: ink[handleIndex].X - deltaX / xScale, Y: ink[handleIndex].Y - deltaY / yScale };
+ ink[handleIndex] = newHandlePoint;
+
+ // Rotating opposite handle (first and final control point only have one handle).
if (handleIndex !== 1 && handleIndex !== ink.length - 2) {
- const oldHandlePoint = ink[handleIndex];
let oppositeHandlePoint = order === 1 ? ink[handleIndex - 3] : ink[handleIndex + 3];
const controlPoint = order === 1 ? ink[handleIndex - 1] : ink[handleIndex + 1];
const angle = this.angleChange(oldHandlePoint, newHandlePoint, controlPoint);
oppositeHandlePoint = this.rotatePoint(oppositeHandlePoint, controlPoint, angle);
- order === 1 ? newPoints[handleIndex - 3] = oppositeHandlePoint : newPoints[handleIndex + 3] = oppositeHandlePoint;
+ order === 1 ? ink[handleIndex - 3] = oppositeHandlePoint : ink[handleIndex + 3] = oppositeHandlePoint;
}
- return newPoints;
- });
-
- // /**
- // * Changes the color of the border of the ink instance.
- // * @param color The new hex value to change the border to.
- // * @returns true.
- // */
- // @undoBatch
- // @action
- // switchStk = (color: ColorState) => {
- // const val = String(color.hex);
- // this.colorStk = val;
- // return true;
- // }
-
- // /**
- // * Changes the color of the fill of the ink instance.
- // * @param color The new hex value to change the fill to.
- // * @returns true.
- // */
- // @undoBatch
- // @action
- // switchFil = (color: ColorState) => {
- // const val = String(color.hex);
- // this.colorFil = val;
- // return true;
- // }
+ return ink;
+ })
} \ No newline at end of file
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
deleted file mode 100644
index b2ef76882..000000000
--- a/src/client/views/InkingStroke.tsx
+++ /dev/null
@@ -1,271 +0,0 @@
-import { action, observable } from "mobx";
-import { observer } from "mobx-react";
-import { Doc } from "../../fields/Doc";
-import { documentSchema } from "../../fields/documentSchemas";
-import { InkData, InkField, InkTool, ControlPoint, HandlePoint, HandleLine } from "../../fields/InkField";
-import { makeInterface } from "../../fields/Schema";
-import { Cast, StrCast } from "../../fields/Types";
-import { TraceMobx } from "../../fields/util";
-import { setupMoveUpEvents, emptyFunction, returnFalse } from "../../Utils";
-import { CognitiveServices } from "../cognitive_services/CognitiveServices";
-import { InteractionUtils } from "../util/InteractionUtils";
-import { Scripting } from "../util/Scripting";
-import { UndoManager } from "../util/UndoManager";
-import { ContextMenu } from "./ContextMenu";
-import { ViewBoxBaseComponent } from "./DocComponent";
-import "./InkingStroke.scss";
-import { FieldView, FieldViewProps } from "./nodes/FieldView";
-import React = require("react");
-import { InkStrokeProperties } from "./InkStrokeProperties";
-import { CurrentUserUtils } from "../util/CurrentUserUtils";
-import { InkControl } from "./InkControl";
-
-type InkDocument = makeInterface<[typeof documentSchema]>;
-const InkDocument = makeInterface(documentSchema);
-
-@observer
-export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocument>(InkDocument) {
- private _controlUndo?: UndoManager.Batch;
- @observable private _overAddPoint = -1;
-
- static readonly MaskDim = 50000;
-
- public static LayoutString(fieldStr: string) { return FieldView.LayoutString(InkingStroke, fieldStr); }
-
- analyzeStrokes = () => {
- const data: InkData = Cast(this.dataDoc[this.fieldKey], InkField)?.inkData ?? [];
- CognitiveServices.Inking.Appliers.ConcatenateHandwriting(this.dataDoc, ["inkAnalysis", "handwriting"], [data]);
- }
-
- @action
- onPointerEnter = (i: number) => {
- this._overAddPoint = i;
- }
-
- @action
- onPointerLeave = () => {
- this._overAddPoint = -1;
- }
-
-
- @action
- public static toggleMask = (inkDoc: Doc) => {
- inkDoc.isInkMask = !inkDoc.isInkMask;
- inkDoc._backgroundColor = inkDoc.isInkMask ? "rgba(0,0,0,0.7)" : undefined;
- inkDoc.mixBlendMode = inkDoc.isInkMask ? "hard-light" : undefined;
- inkDoc.color = "#9b9b9bff";
- inkDoc._stayInCollection = inkDoc.isInkMask ? true : undefined;
- };
-
- /**
- * Handles the movement of a selected control point when the user clicks and drags.
- * @param controlNum The index of the currently selected control point.
- */
- @action
- onControlDown = (e: React.PointerEvent, controlNum: number): void => {
- if (InkStrokeProperties.Instance) {
- InkStrokeProperties.Instance.moveControl(0, 0, 1);
- const controlUndo = UndoManager.StartBatch("DocDecs set radius");
- const screenScale = this.props.ScreenToLocalTransform().Scale;
- setupMoveUpEvents(this, e,
- (e: PointerEvent, down: number[], delta: number[]) => {
- InkStrokeProperties.Instance?.moveControl(-delta[0] * screenScale, -delta[1] * screenScale, controlNum);
- return false;
- },
- () => controlUndo?.end(), emptyFunction);
- }
- }
-
- /**
- * Handles the movement of a selected handle point when the user clicks and drags.
- * @param controlNum The index of the currently selected handle point.
- */
- onHandleDown = (e: React.PointerEvent, handleNum: number): void => {
- if (InkStrokeProperties.Instance) {
- InkStrokeProperties.Instance.moveControl(0, 0, 1);
- const controlUndo = UndoManager.StartBatch("DocDecs set radius");
- const screenScale = this.props.ScreenToLocalTransform().Scale;
- setupMoveUpEvents(this, e,
- (e: PointerEvent, down: number[], delta: number[]) => {
- InkStrokeProperties.Instance?.moveHandle(-delta[0] * screenScale, -delta[1] * screenScale, handleNum);
- return false;
- },
- () => controlUndo?.end(), emptyFunction);
- }
- }
-
- /**
- * Handles the movement of the entire ink object when the user clicks and drags.
- * @param e React Pointer Event.
- */
- onPointerDown = (e: React.PointerEvent) => {
- if (this.props.isSelected(true)) {
- setupMoveUpEvents(this, e, returnFalse, emptyFunction, action((e: PointerEvent, doubleTap: boolean | undefined) =>
- doubleTap && InkStrokeProperties.Instance && (InkStrokeProperties.Instance._controlBtn = true)));
- }
- }
-
- render() {
- TraceMobx();
- const formatInstance = InkStrokeProperties.Instance;
- if (!formatInstance) return (null);
- const data: InkData = Cast(this.dataDoc[this.fieldKey], InkField)?.inkData ?? [];
- const strokeWidth = Number(this.layoutDoc.strokeWidth);
- const xs = data.map(p => p.X);
- const ys = data.map(p => p.Y);
- const lineTop = Math.min(...ys);
- const lineBot = Math.max(...ys);
- const lineLft = Math.min(...xs);
- const lineRgt = Math.max(...xs);
- const left = lineLft - strokeWidth / 2;
- const top = lineTop - strokeWidth / 2;
- const right = lineRgt + strokeWidth / 2;
- const bottom = lineBot + strokeWidth / 2;
- const width = Math.max(1, right - left);
- const height = Math.max(1, bottom - top);
- const scaleX = width === strokeWidth ? 1 : (this.props.PanelWidth() - strokeWidth) / (width - strokeWidth);
- const scaleY = height === strokeWidth ? 1 : (this.props.PanelHeight() - strokeWidth) / (height - strokeWidth);
- const strokeColor = StrCast(this.layoutDoc.color, "");
- const dotsize = Math.max(width * scaleX, height * scaleY) / 40;
-
- // Visually renders the polygonal line made by the user.
- const points = InteractionUtils.CreatePolyline(data, left, top, strokeColor, strokeWidth, strokeWidth,
- StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "none"),
- StrCast(this.layoutDoc.strokeStartMarker), StrCast(this.layoutDoc.strokeEndMarker),
- StrCast(this.layoutDoc.strokeDash), scaleX, scaleY, "", "none", this.props.isSelected() && strokeWidth <= 5 && lineBot - lineTop > 1 && lineRgt - lineLft > 1, false);
-
- const selectedLine = InteractionUtils.CreatePolyline(data, lineLft - strokeWidth * 3, lineTop - strokeWidth * 3, "#1F85DE", strokeWidth / 6, strokeWidth / 6,
- StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "none"),
- StrCast(this.layoutDoc.strokeStartMarker), StrCast(this.layoutDoc.strokeEndMarker),
- StrCast(this.layoutDoc.strokeDash), scaleX, scaleY, "", "none", this.props.isSelected() && strokeWidth <= 5 && lineBot - lineTop > 1 && lineRgt - lineLft > 1, false);
-
- // Invisible polygonal line that enables the ink to be selected by the user.
- const hpoints = InteractionUtils.CreatePolyline(data, left, top,
- this.props.isSelected() && strokeWidth > 5 ? strokeColor : "transparent", strokeWidth, (strokeWidth + 15),
- StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "none"),
- "none", "none", undefined, scaleX, scaleY, "", this.props.layerProvider?.(this.props.Document) === false ? "none" : "visiblepainted", false, true);
-
- const apoints = InteractionUtils.CreatePoints(data, left, top, strokeColor, strokeWidth, strokeWidth,
- StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "none"),
- StrCast(this.layoutDoc.strokeStartMarker), StrCast(this.layoutDoc.strokeEndMarker),
- StrCast(this.layoutDoc.strokeDash), scaleX, scaleY, "", "none", this.props.isSelected() && strokeWidth <= 5, false);
-
- const controlPoints: ControlPoint[] = [];
- const handlePoints: HandlePoint[] = [];
- const handleLine: HandleLine[] = [];
- // check the purpose of this conditional
- if (data.length >= 4) {
-
- // create separate functions for these
- for (var i = 0; i <= data.length - 4; i += 4) {
- controlPoints.push({ X: data[i].X, Y: data[i].Y, I: i });
- controlPoints.push({ X: data[i + 3].X, Y: data[i + 3].Y, I: i + 3 });
- handlePoints.push({ X: data[i + 1].X, Y: data[i + 1].Y, I: i + 1, dot1: i, dot2: i === 0 ? i : i - 1 });
- handlePoints.push({ X: data[i + 2].X, Y: data[i + 2].Y, I: i + 2, dot1: i + 3, dot2: i === data.length ? i + 3 : i + 4 });
- }
-
- // first (single) handle line
- handleLine.push({ X1: data[0].X, Y1: data[0].Y, X2: data[1].X, Y2: data[1].Y, dot1: 0, dot2: 0 });
- for (var i = 2; i < data.length - 4; i += 4) {
-
- handleLine.push({ X1: data[i].X, Y1: data[i].Y, X2: data[i + 3].X, Y2: data[i + 3].Y, dot1: i + 1, dot2: i + 2 });
-
- }
- // last (single) handle line
- handleLine.push({ X1: data[data.length - 2].X, Y1: data[data.length - 2].Y, X2: data[data.length - 1].X, Y2: data[data.length - 1].Y, dot1: data.length - 1, dot2: data.length - 1 });
-
- for (var i = 0; i <= data.length - 4; i += 4) {
- handlePoints.push({ X: data[i + 1].X, Y: data[i + 1].Y, I: i + 1, dot1: i, dot2: i === 0 ? i : i - 1 });
- handlePoints.push({ X: data[i + 2].X, Y: data[i + 2].Y, I: i + 2, dot1: i + 3, dot2: i === data.length ? i + 3 : i + 4 });
- }
- }
-
- // Additional points (controls) added by the user via click when editing the ink's format.
- const addpoints = apoints.map((pts, i) =>
- <svg height="10" width="10" key={`add${i}`}>
- <circle cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} r={strokeWidth / 2} stroke={this._overAddPoint === i ? "#1F85DE" : "invisible"} strokeWidth={dotsize / 4} fill={this._overAddPoint === i ? "#1F85DE" : "invisible"}
- onPointerDown={(e) => { formatInstance.addPoints(pts.X, pts.Y, apoints, i, controlPoints); }} onMouseEnter={() => this.onPointerEnter(i)} onMouseLeave={this.onPointerLeave} pointerEvents="all" cursor="all-scroll"
- />
- </svg>);
- // Blue circles that allow the user to edit the curvature of the line using the selected control point as the anchor.
- const handles = handlePoints.map((pts, i) =>
- <svg height="10" width="10" key={`hdl${i}`}>
- <circle cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} r={strokeWidth / 2} strokeWidth={0} fill="#1F85DE"
- onPointerDown={(e) => this.onHandleDown(e, pts.I)} pointerEvents="all" cursor="default" display={(pts.dot1 === formatInstance._currPoint || pts.dot2 === formatInstance._currPoint) ? "inherit" : "none"} />
- </svg>);
- // Control points of the ink (blue outlined squares) that are made visible to user when editing its format.
- const controls = controlPoints.map((pts, i) => <InkControl control={pts} left={left} top={top} scaleX={scaleX} scaleY={scaleY} strokeWidth={strokeWidth} ScreenToLocalTransform={this.props.ScreenToLocalTransform} /> );
- // Set of two blue lines (each with a handle at the end) that are rendered perpendicular to the current selected point while editing.
- const handleLines = handleLine.map((pts, i) =>
- <svg height="100" width="100" key={`line${i}`}>
- <line x1={(pts.X1 - left - strokeWidth / 2) * scaleX + strokeWidth / 2} y1={(pts.Y1 - top - strokeWidth / 2) * scaleY + strokeWidth / 2}
- x2={(pts.X2 - left - strokeWidth / 2) * scaleX + strokeWidth / 2} y2={(pts.Y2 - top - strokeWidth / 2) * scaleY + strokeWidth / 2} stroke="#1F85DE" strokeWidth={dotsize / 10}
- display={(pts.dot1 === formatInstance._currPoint || pts.dot2 === formatInstance._currPoint) ? "inherit" : "none"} />
- </svg>);
-
- return (
- <svg className="inkingStroke"
- style={{
- pointerEvents: this.props.Document.isInkMask && this.props.layerProvider?.(this.props.Document) !== false ? "all" : "none",
- transform: this.props.Document.isInkMask ? `translate(${InkingStroke.MaskDim / 2}px, ${InkingStroke.MaskDim / 2}px)` : undefined,
- mixBlendMode: this.layoutDoc.tool === InkTool.Highlighter ? "multiply" : "unset",
- overflow: "visible",
- }}
- onPointerDown={this.onPointerDown}
- onContextMenu={() => {
- const cm = ContextMenu.Instance;
- if (cm) {
- !Doc.UserDoc().noviceMode && cm.addItem({ description: "Recognize Writing", event: this.analyzeStrokes, icon: "paint-brush" });
- cm.addItem({ description: "Toggle Mask", event: () => InkingStroke.toggleMask(this.rootDoc), icon: "paint-brush" });
- cm.addItem({ description: "Edit Points", event: action(() => formatInstance._controlBtn = !formatInstance._controlBtn), icon: "paint-brush" });
- //cm.addItem({ description: "Format Shape...", event: this.formatShape, icon: "paint-brush" });
- }
- }}
- ><defs>
- </defs>
- {hpoints}
- {points}
- {formatInstance._controlBtn && this.props.isSelected() ? addpoints : ""}
- {formatInstance._controlBtn && this.props.isSelected() ? handleLines : ""}
- {formatInstance._controlBtn && this.props.isSelected() ? handles : ""}
- {this.props.isSelected() ? selectedLine : ""}
- {formatInstance._controlBtn && this.props.isSelected() ? controls : ""}
- </svg>
- );
- }
-}
-
-
-export function SetActiveInkWidth(width: string): void { !isNaN(parseInt(width)) && ActiveInkPen() && (ActiveInkPen().activeInkWidth = width); }
-export function SetActiveBezierApprox(bezier: string): void { ActiveInkPen() && (ActiveInkPen().activeInkBezier = isNaN(parseInt(bezier)) ? "" : bezier); }
-export function SetActiveInkColor(value: string) { ActiveInkPen() && (ActiveInkPen().activeInkColor = value); }
-export function SetActiveFillColor(value: string) { ActiveInkPen() && (ActiveInkPen().activeFillColor = value); }
-export function SetActiveArrowStart(value: string) { ActiveInkPen() && (ActiveInkPen().activeArrowStart = value); }
-export function SetActiveArrowEnd(value: string) { ActiveInkPen() && (ActiveInkPen().activeArrowEnd = value); }
-export function SetActiveDash(dash: string): void { !isNaN(parseInt(dash)) && ActiveInkPen() && (ActiveInkPen().activeDash = dash); }
-export function ActiveInkPen(): Doc { return Doc.UserDoc(); }
-export function ActiveInkColor(): string { return StrCast(ActiveInkPen()?.activeInkColor, "black"); }
-export function ActiveFillColor(): string { return StrCast(ActiveInkPen()?.activeFillColor, ""); }
-export function ActiveArrowStart(): string { return StrCast(ActiveInkPen()?.activeArrowStart, ""); }
-export function ActiveArrowEnd(): string { return StrCast(ActiveInkPen()?.activeArrowEnd, ""); }
-export function ActiveDash(): string { return StrCast(ActiveInkPen()?.activeDash, "0"); }
-export function ActiveInkWidth(): string { return StrCast(ActiveInkPen()?.activeInkWidth, "1"); }
-export function ActiveInkBezierApprox(): string { return StrCast(ActiveInkPen()?.activeInkBezier); }
-Scripting.addGlobal(function activateBrush(pen: any, width: any, color: any, fill: any, arrowStart: any, arrowEnd: any, dash: any) {
- CurrentUserUtils.SelectedTool = pen ? InkTool.Highlighter : InkTool.None;
- SetActiveInkWidth(width);
- SetActiveInkColor(color);
- SetActiveFillColor(fill);
- SetActiveArrowStart(arrowStart);
- SetActiveArrowEnd(arrowEnd);
- SetActiveDash(dash);
-});
-Scripting.addGlobal(function activateEraser(pen: any) { return CurrentUserUtils.SelectedTool = pen ? InkTool.Eraser : InkTool.None; });
-Scripting.addGlobal(function activateStamp(pen: any) { return CurrentUserUtils.SelectedTool = pen ? InkTool.Stamp : InkTool.None; });
-Scripting.addGlobal(function deactivateInk() { return CurrentUserUtils.SelectedTool = InkTool.None; });
-Scripting.addGlobal(function setInkWidth(width: any) { return SetActiveInkWidth(width); });
-Scripting.addGlobal(function setInkColor(color: any) { return SetActiveInkColor(color); });
-Scripting.addGlobal(function setFillColor(fill: any) { return SetActiveFillColor(fill); });
-Scripting.addGlobal(function setActiveArrowStart(arrowStart: any) { return SetActiveArrowStart(arrowStart); });
-Scripting.addGlobal(function setActiveArrowEnd(arrowEnd: any) { return SetActiveArrowStart(arrowEnd); });
-Scripting.addGlobal(function setActiveDash(dash: any) { return SetActiveDash(dash); });
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 5c41a96d0..920244463 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -11,7 +11,7 @@ import { DocumentType } from '../documents/DocumentTypes';
import { SelectionManager } from '../util/SelectionManager';
import { undoBatch } from '../util/UndoManager';
import { CollectionViewType } from './collections/CollectionView';
-import { InkingStroke } from './InkingStroke';
+import { InkStroke } from './InkStroke';
import { DocumentView } from './nodes/DocumentView';
import './PropertiesButtons.scss';
import React = require("react");
@@ -56,7 +56,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
return this.propertyToggleBtn("Dictate", "_showAudio", on => `${on ? "Hide" : "Show"} dictation/recording controls`, on => "microphone");
}
@computed get maskButton() {
- return this.propertyToggleBtn("Mask", "isInkMask", on => on ? "Make plain ink" : "Make highlight mask", on => "paint-brush", (dv, doc) => InkingStroke.toggleMask(dv?.layoutDoc || doc));
+ return this.propertyToggleBtn("Mask", "isInkMask", on => on ? "Make plain ink" : "Make highlight mask", on => "paint-brush", (dv, doc) => InkStroke.toggleMask(dv?.layoutDoc || doc));
}
@computed get clustersButton() {
return this.propertyToggleBtn("Clusters", "_useClusters", on => `${on ? "Hide" : "Show"} clusters`, on => "braille");
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index d09d949ff..4df3e4f00 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -86,7 +86,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
@observable openSlideOptions: boolean = false;
@observable inOptions: boolean = false;
- @observable _controlBtn: boolean = false;
+ @observable _controlButton: boolean = false;
@observable _lock: boolean = false;
componentDidMount() {
@@ -540,7 +540,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
const formatInstance = InkStrokeProperties.Instance;
return !formatInstance ? (null) : <div className="inking-button">
<Tooltip title={<div className="dash-tooltip">{"Edit points"}</div>}>
- <div className="inking-button-points" onPointerDown={action(() => formatInstance._controlBtn = !formatInstance._controlBtn)} style={{ backgroundColor: formatInstance._controlBtn ? "black" : "" }}>
+ <div className="inking-button-points" onPointerDown={action(() => formatInstance._controlButton = !formatInstance._controlButton)} style={{ backgroundColor: formatInstance._controlButton ? "black" : "" }}>
<FontAwesomeIcon icon="bezier-curve" color="white" size="lg" />
</div>
</Tooltip>
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 6e6fabd0d..65061d260 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -25,7 +25,7 @@ import { undoBatch } from "../../util/UndoManager";
import { AntimodeMenu, AntimodeMenuProps } from "../AntimodeMenu";
import { EditableView } from "../EditableView";
import { GestureOverlay } from "../GestureOverlay";
-import { ActiveFillColor, ActiveInkColor, SetActiveArrowEnd, SetActiveArrowStart, SetActiveBezierApprox, SetActiveFillColor, SetActiveInkColor, SetActiveInkWidth, ActiveArrowStart, ActiveArrowEnd } from "../InkingStroke";
+import { ActiveFillColor, ActiveInkColor, SetActiveArrowEnd, SetActiveArrowStart, SetActiveBezierApprox, SetActiveFillColor, SetActiveInkColor, SetActiveInkWidth, ActiveArrowStart, ActiveArrowEnd } from "../InkStroke";
import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
import { DocumentView } from "../nodes/DocumentView";
import { RichTextMenu } from "../nodes/formattedText/RichTextMenu";
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index accb80c5a..9e81a6cda 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -32,7 +32,7 @@ import { COLLECTION_BORDER_WIDTH } from "../../../views/globalCssVariables.scss"
import { Timeline } from "../../animationtimeline/Timeline";
import { ContextMenu } from "../../ContextMenu";
import { DocumentDecorations } from "../../DocumentDecorations";
-import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth } from "../../InkingStroke";
+import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth } from "../../InkStroke";
import { LightboxView } from "../../LightboxView";
import { CollectionFreeFormDocumentView } from "../../nodes/CollectionFreeFormDocumentView";
import { DocFocusOptions, DocumentView, DocumentViewProps, ViewAdjustment, ViewSpecPrefix } from "../../nodes/DocumentView";
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 092823603..744a9c5de 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -13,7 +13,7 @@ import { SelectionManager } from "../../util/SelectionManager";
import { Transform } from "../../util/Transform";
import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView";
import { DocComponent } from "../DocComponent";
-import { InkingStroke } from "../InkingStroke";
+import { InkStroke } from "../InkStroke";
import { StyleProp } from "../StyleProvider";
import "./CollectionFreeFormDocumentView.scss";
import { DocumentView, DocumentViewProps } from "./DocumentView";
@@ -38,7 +38,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
@observable _animPos: number[] | undefined = undefined;
@observable _contentView: DocumentView | undefined | null;
get displayName() { return "CollectionFreeFormDocumentView(" + this.rootDoc.title + ")"; } // this makes mobx trace() statements more descriptive
- get maskCentering() { return this.props.Document.isInkMask ? InkingStroke.MaskDim / 2 : 0; }
+ get maskCentering() { return this.props.Document.isInkMask ? InkStroke.MaskDim / 2 : 0; }
get transform() { return `translate(${this.X - this.maskCentering}px, ${this.Y - this.maskCentering}px) rotate(${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); }
diff --git a/src/client/views/nodes/ColorBox.tsx b/src/client/views/nodes/ColorBox.tsx
index 8da5cd1b1..2d466763b 100644
--- a/src/client/views/nodes/ColorBox.tsx
+++ b/src/client/views/nodes/ColorBox.tsx
@@ -12,7 +12,7 @@ import { CurrentUserUtils } from "../../util/CurrentUserUtils";
import { SelectionManager } from "../../util/SelectionManager";
import { undoBatch } from "../../util/UndoManager";
import { ViewBoxBaseComponent } from "../DocComponent";
-import { ActiveInkColor, ActiveInkWidth, SetActiveInkColor, SetActiveInkWidth } from "../InkingStroke";
+import { ActiveInkColor, ActiveInkWidth, SetActiveInkColor, SetActiveInkWidth } from "../InkStroke";
import "./ColorBox.scss";
import { FieldView, FieldViewProps } from './FieldView';
import { RichTextMenu } from "./formattedText/RichTextMenu";
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index f0a54e4ac..5da3a52d5 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -10,7 +10,7 @@ import { CollectionDockingView } from "../collections/CollectionDockingView";
import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView";
import { CollectionSchemaView } from "../collections/CollectionSchemaView";
import { CollectionView } from "../collections/CollectionView";
-import { InkingStroke } from "../InkingStroke";
+import { InkStroke } from "../InkStroke";
import { PresElementBox } from "../presentationview/PresElementBox";
import { SearchBox } from "../search/SearchBox";
import { DashWebRTCVideo } from "../webcam/DashWebRTCVideo";
@@ -224,7 +224,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & Fo
FormattedTextBox, ImageBox, DirectoryImportBox, FontIconBox, LabelBox, EquationBox, SliderBox, FieldView,
CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, WebBox, KeyValueBox,
PDFBox, VideoBox, AudioBox, PresBox, YoutubeBox, PresElementBox, SearchBox, FilterBox, FunctionPlotBox,
- ColorBox, DashWebRTCVideo, LinkAnchorBox, InkingStroke, LinkBox, ScriptingBox,
+ ColorBox, DashWebRTCVideo, LinkAnchorBox, InkStroke, LinkBox, ScriptingBox,
ScreenshotBox,
HTMLtag, ComparisonBox
}}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index b861669f8..924b0e7d3 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -34,7 +34,7 @@ import { ContextMenu } from "../ContextMenu";
import { ContextMenuProps } from '../ContextMenuItem';
import { DocComponent } from "../DocComponent";
import { EditableView } from '../EditableView';
-import { InkingStroke } from "../InkingStroke";
+import { InkStroke } from "../InkStroke";
import { LightboxView } from "../LightboxView";
import { StyleLayers, StyleProp } from "../StyleProvider";
import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView";
@@ -1138,8 +1138,8 @@ export class DocumentView extends React.Component<DocumentViewProps> {
render() {
TraceMobx();
- const xshift = () => (this.props.Document.isInkMask ? InkingStroke.MaskDim : Math.abs(this.Xshift) <= 0.001 ? this.props.PanelWidth() : undefined);
- const yshift = () => (this.props.Document.isInkMask ? InkingStroke.MaskDim : Math.abs(this.Yshift) <= 0.001 ? this.props.PanelHeight() : undefined);
+ const xshift = () => (this.props.Document.isInkMask ? InkStroke.MaskDim : Math.abs(this.Xshift) <= 0.001 ? this.props.PanelWidth() : undefined);
+ const yshift = () => (this.props.Document.isInkMask ? InkStroke.MaskDim : Math.abs(this.Yshift) <= 0.001 ? this.props.PanelHeight() : undefined);
return (<div className="contentFittingDocumentView">
{!this.props.Document || !this.props.PanelWidth() ? (null) : (
<div className="contentFittingDocumentView-previewDoc" ref={this.ContentRef}