aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/InkingStroke.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/InkingStroke.tsx')
-rw-r--r--src/client/views/InkingStroke.tsx157
1 files changed, 62 insertions, 95 deletions
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 51baaa23e..f497ca447 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -23,30 +23,33 @@
import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
+import { DashColor, returnFalse, setupMoveUpEvents } from '../../ClientUtils';
import { Doc } from '../../fields/Doc';
import { InkData, InkField } from '../../fields/InkField';
import { BoolCast, Cast, NumCast, RTFCast, StrCast } from '../../fields/Types';
import { TraceMobx } from '../../fields/util';
-import { DashColor, returnFalse, setupMoveUpEvents } from '../../Utils';
import { CognitiveServices } from '../cognitive_services/CognitiveServices';
import { Docs } from '../documents/Documents';
+import { DocumentType } from '../documents/DocumentTypes';
import { InteractionUtils } from '../util/InteractionUtils';
import { SnappingManager } from '../util/SnappingManager';
import { UndoManager } from '../util/UndoManager';
import { ContextMenu } from './ContextMenu';
-import { ViewBoxAnnotatableComponent, ViewBoxBaseComponent, ViewBoxInterface } from './DocComponent';
+import { ViewBoxAnnotatableComponent, ViewBoxInterface } from './DocComponent';
import { Colors } from './global/globalEnums';
import { InkControlPtHandles, InkEndPtHandles } from './InkControlPtHandles';
import './InkStroke.scss';
import { InkStrokeProperties } from './InkStrokeProperties';
import { InkTangentHandles } from './InkTangentHandles';
import { FieldView, FieldViewProps } from './nodes/FieldView';
-import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
-import { PinProps, PresBox } from './nodes/trails';
-import { StyleProp } from './StyleProvider';
+import { FormattedTextBox, FormattedTextBoxProps } from './nodes/formattedText/FormattedTextBox';
+import { PinDocView, PinProps } from './PinFuncs';
+import { StyleProp } from './StyleProp';
+
const { INK_MASK_SIZE } = require('./global/globalCssVariables.module.scss'); // prettier-ignore
+
@observer
-export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>() implements ViewBoxInterface {
+export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>() {
static readonly MaskDim = INK_MASK_SIZE; // choose a really big number to make sure mask fits over container (which in theory can be arbitrarily big)
public static LayoutString(fieldStr: string) {
return FieldView.LayoutString(InkingStroke, fieldStr);
@@ -65,7 +68,9 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
this._props.setContentViewBox?.(this);
this._disposers.selfDisper = reaction(
() => this._props.isSelected(), // react to stroke being deselected by turning off ink handles
- selected => !selected && (InkStrokeProperties.Instance._controlButton = false)
+ selected => {
+ !selected && (InkStrokeProperties.Instance._controlButton = false);
+ }
);
}
componentWillUnmount() {
@@ -88,7 +93,7 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
if (anchor) {
anchor.backgroundColor = 'transparent';
addAsAnnotation && this.addDocument(anchor);
- PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), inkable: true } }, this.Document);
+ PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), inkable: true } }, this.Document);
return anchor;
}
return this.Document;
@@ -140,7 +145,7 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
e,
!isEditing
? returnFalse
- : action((e: PointerEvent, down: number[], delta: number[]) => {
+ : action((moveEv: PointerEvent, down: number[], delta: number[]) => {
if (!this.controlUndo) this.controlUndo = UndoManager.StartBatch('drag ink ctrl pt');
const inkMoveEnd = this.ptFromScreen({ X: delta[0], Y: delta[1] });
const inkMoveStart = this.ptFromScreen({ X: 0, Y: 0 });
@@ -155,7 +160,7 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
this.controlUndo = undefined;
UndoManager.FilterBatches(['data', 'x', 'y', 'width', 'height']);
}),
- action((e: PointerEvent, doubleTap: boolean | undefined) => {
+ action((moveEv: PointerEvent, doubleTap: boolean | undefined) => {
if (doubleTap) {
InkStrokeProperties.Instance._controlButton = true;
InkStrokeProperties.Instance._currentPoint = -1;
@@ -167,7 +172,9 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
}),
isEditing,
isEditing,
- action(() => wasSelected && (InkStrokeProperties.Instance._currentPoint = -1))
+ action(() => {
+ wasSelected && (InkStrokeProperties.Instance._currentPoint = -1);
+ })
);
};
@@ -325,32 +332,34 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
false
)}
<InkControlPtHandles inkView={this} inkDoc={inkDoc} inkCtrlPoints={inkData} screenCtrlPoints={this.screenCtrlPts} nearestScreenPt={this.nearestScreenPt} screenSpaceLineWidth={screenSpaceCenterlineStrokeWidth} />
- <InkTangentHandles inkView={this} inkDoc={inkDoc} screenCtrlPoints={this.screenCtrlPts} screenSpaceLineWidth={screenSpaceCenterlineStrokeWidth} ScreenToLocalTransform={this.ScreenToLocalBoxXf} />
+ <InkTangentHandles inkView={this} inkDoc={inkDoc} screenCtrlPoints={this.screenCtrlPts} screenSpaceLineWidth={screenSpaceCenterlineStrokeWidth} />
</div>
);
};
- _subContentView: ViewBoxInterface | undefined;
- setSubContentView = (doc: ViewBoxInterface) => (this._subContentView = doc);
- @computed get fillColor() {
+ _subContentView: ViewBoxInterface<FormattedTextBoxProps> | undefined;
+ setSubContentView = (box: ViewBoxInterface<FormattedTextBoxProps>) => {
+ this._subContentView = box;
+ };
+ @computed get fillColor(): string {
const isInkMask = BoolCast(this.layoutDoc.stroke_isInkMask);
return isInkMask ? DashColor(StrCast(this.layoutDoc.fillColor, 'transparent')).blacken(0).rgb().toString() : this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FillColor) ?? 'transparent';
}
@computed get strokeColor() {
const { inkData } = this.inkScaledData();
- const fillColor = this.fillColor;
+ const { fillColor } = this;
return !InkingStroke.IsClosed(inkData) && fillColor && fillColor !== 'transparent' ? fillColor : this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) ?? StrCast(this.layoutDoc.color);
}
render() {
TraceMobx();
- const { inkData, inkStrokeWidth, inkLeft, inkTop, inkScaleX, inkScaleY, inkWidth, inkHeight } = this.inkScaledData();
+ const { inkData, inkStrokeWidth, inkLeft, inkTop, inkScaleX, inkScaleY } = this.inkScaledData();
const startMarker = StrCast(this.layoutDoc.stroke_startMarker);
const endMarker = StrCast(this.layoutDoc.stroke_endMarker);
const markerScale = NumCast(this.layoutDoc.stroke_markerScale, 1);
const closed = InkingStroke.IsClosed(inkData);
const isInkMask = BoolCast(this.layoutDoc.stroke_isInkMask);
- const fillColor = this.fillColor;
+ const { fillColor } = this;
// bcz: Hack!! Not really sure why, but having fractional values for width/height of mask ink strokes causes the dragging clone (see DragManager) to be offset from where it should be.
if (isInkMask && (this.layoutDoc._width !== Math.round(NumCast(this.layoutDoc._width)) || this.layoutDoc._height !== Math.round(NumCast(this.layoutDoc._height)))) {
@@ -387,12 +396,11 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
1.0,
false,
undefined,
- undefined,
- color === 'transparent' ? highlightColor : undefined
+ undefined
);
const higlightMargin = Math.min(12, Math.max(2, 0.3 * inkStrokeWidth));
// Invisible polygonal line that enables the ink to be selected by the user.
- const clickableLine = (downHdlr?: (e: React.PointerEvent) => void, mask: boolean = false) =>
+ const clickableLine = (downHdlr?: (e: React.PointerEvent) => void, mask: boolean = false): any =>
InteractionUtils.CreatePolyline(
inkData,
inkLeft,
@@ -415,22 +423,29 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
0.0,
false,
downHdlr,
- mask,
- highlightColor
+ mask
);
// bootsrap 3 style sheet sets line height to be 20px for default 14 point font size.
// this attempts to figure out the lineHeight ratio by inquiring the body's lineHeight and dividing by the fontsize which should yield 1.428571429
// see: https://bibwild.wordpress.com/2019/06/10/bootstrap-3-to-4-changes-in-how-font-size-line-height-and-spacing-is-done-or-what-happened-to-line-height-computed/
- const lineHeightGuess = +getComputedStyle(document.body).lineHeight.replace('px', '') / +getComputedStyle(document.body).fontSize.replace('px', '');
+ // const lineHeightGuess = +getComputedStyle(document.body).lineHeight.replace('px', '') / +getComputedStyle(document.body).fontSize.replace('px', '');
const interactions = {
- onPointerLeave: action(() => (this._nearestScrPt = undefined)),
+ onPointerLeave: action(() => {
+ this._nearestScrPt = undefined;
+ }),
onPointerMove: this._props.isSelected() ? this.onPointerMove : undefined,
onClick: (e: React.MouseEvent) => this._handledClick && e.stopPropagation(),
onContextMenu: () => {
const cm = ContextMenu.Instance;
!Doc.noviceMode && cm?.addItem({ description: 'Recognize Writing', event: this.analyzeStrokes, icon: 'paint-brush' });
cm?.addItem({ description: 'Toggle Mask', event: () => InkingStroke.toggleMask(this.dataDoc), icon: 'paint-brush' });
- cm?.addItem({ description: 'Edit Points', event: action(() => (InkStrokeProperties.Instance._controlButton = !InkStrokeProperties.Instance._controlButton)), icon: 'paint-brush' });
+ cm?.addItem({
+ description: 'Edit Points',
+ event: action(() => {
+ InkStrokeProperties.Instance._controlButton = !InkStrokeProperties.Instance._controlButton;
+ }),
+ icon: 'paint-brush',
+ });
},
};
return (
@@ -438,10 +453,11 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
<svg
className="inkStroke"
style={{
- transform: isInkMask ? `rotate(-${NumCast(this._props.CollectionFreeFormDocumentView?.()._props.rotation ?? 0)}deg) translate(${InkingStroke.MaskDim / 2}px, ${InkingStroke.MaskDim / 2}px)` : undefined,
+ transform: isInkMask ? `rotate(-${NumCast(this._props.LocalRotation?.() ?? 0)}deg) translate(${InkingStroke.MaskDim / 2}px, ${InkingStroke.MaskDim / 2}px)` : undefined,
// mixBlendMode: this.layoutDoc.tool === InkTool.Highlighter ? 'multiply' : 'unset',
cursor: this._props.isSelected() ? 'default' : undefined,
}}
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...interactions}>
{clickableLine(this.onPointerDown, isInkMask)}
{isInkMask ? null : inkLine}
@@ -455,18 +471,19 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
width: NumCast(this.layoutDoc._width),
transform: `scale(${this._props.NativeDimScaling?.() || 1})`,
transformOrigin: 'top left',
- //top: (this._props.PanelHeight() - (lineHeightGuess * fsize + 20) * (this._props.NativeDimScaling?.() || 1)) / 2,
+ // top: (this._props.PanelHeight() - (lineHeightGuess * fsize + 20) * (this._props.NativeDimScaling?.() || 1)) / 2,
}}>
<FormattedTextBox
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
setHeight={undefined}
setContentViewBox={this.setSubContentView} // this makes the inkingStroke the "dominant" component - ie, it will show the inking UI when selected (not text)
yPadding={10}
xPadding={10}
fieldKey="text"
- //dontRegisterView={true}
- noSidebar={true}
- dontScale={true}
+ // dontRegisterView={true}
+ noSidebar
+ dontScale
isContentActive={this._props.isContentActive}
/>
</div>
@@ -475,67 +492,17 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
);
}
}
-
-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 SetActiveIsInkMask(value: boolean) {
- ActiveInkPen() && (ActiveInkPen().activeIsInkMask = value);
-}
-export function SetActiveInkHideTextLabels(value: boolean) {
- ActiveInkPen() && (ActiveInkPen().activeInkHideTextLabels = 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 SetActiveArrowScale(value: number) {
- ActiveInkPen() && (ActiveInkPen().activeArrowScale = 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 ActiveIsInkMask(): boolean {
- return BoolCast(ActiveInkPen()?.activeIsInkMask, false);
-}
-export function ActiveInkHideTextLabels(): boolean {
- return BoolCast(ActiveInkPen().activeInkHideTextLabels, false);
-}
-export function ActiveArrowStart(): string {
- return StrCast(ActiveInkPen()?.activeArrowStart, '');
-}
-export function ActiveArrowEnd(): string {
- return StrCast(ActiveInkPen()?.activeArrowEnd, '');
-}
-export function ActiveArrowScale(): number {
- return NumCast(ActiveInkPen()?.activeArrowScale, 1);
-}
-export function ActiveDash(): string {
- return StrCast(ActiveInkPen()?.activeDash, '0');
-}
-export function ActiveInkWidth(): number {
- return Number(ActiveInkPen()?.activeInkWidth);
-}
-export function ActiveInkBezierApprox(): string {
- return StrCast(ActiveInkPen()?.activeInkBezier);
-}
+Docs.Prototypes.TemplateMap.set(DocumentType.INK, {
+ // NOTE: this is unused!! ink fields are filled in directly within the InkDocument() method
+ layout: { view: InkingStroke, dataField: 'stroke' },
+ options: {
+ acl: '',
+ systemIcon: 'BsFillPencilFill', //
+ _layout_nativeDimEditable: true,
+ _layout_reflowVertical: true,
+ _layout_reflowHorizontal: true,
+ layout_hideDecorationTitle: true, // don't show title when selected
+ _layout_fitWidth: false,
+ layout_isSvg: true,
+ },
+});