aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2021-11-17 21:35:53 -0500
committerbobzel <zzzman@gmail.com>2021-11-17 21:35:53 -0500
commitb3528b0805b6977f4554c5024fbdd194b3a0f11d (patch)
treef6d12ed118ae5b6e562ab57fb6534d536de07300 /src
parent4ee47eae8735adf4c543c0de4859a09dee10cbf0 (diff)
parent1c0ca018dce4392a91b37ab20b936aa137c1e8a9 (diff)
Merge branch 'master' into treeviewFixing
Diffstat (limited to 'src')
-rw-r--r--src/client/views/InkStroke.scss31
-rw-r--r--src/client/views/InkingStroke.tsx32
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx34
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx14
4 files changed, 82 insertions, 29 deletions
diff --git a/src/client/views/InkStroke.scss b/src/client/views/InkStroke.scss
index 55e06c6ca..2127826b4 100644
--- a/src/client/views/InkStroke.scss
+++ b/src/client/views/InkStroke.scss
@@ -13,16 +13,25 @@
}
}
-.inkStroke {
- mix-blend-mode: multiply;
- stroke-linejoin: round;
- stroke-linecap: round;
- overflow: visible !important;
- transform-origin: top left;
- width: 100%;
- height: 100%;
+.inkStroke-wrapper {
+ .inkStroke {
+ mix-blend-mode: multiply;
+ stroke-linejoin: round;
+ stroke-linecap: round;
+ overflow: visible !important;
+ transform-origin: top left;
+ width: 100%;
+ height: 100%;
- svg:not(:root) {
- overflow: visible !important;
- }
+ svg:not(:root) {
+ overflow: visible !important;
+ }
+ }
+
+ .inkStroke-text {
+ position: absolute;
+ &:hover {
+ background: #9f9f9f0a;
+ }
+ }
}
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index ecb46a5b3..59efb36dd 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -1,13 +1,13 @@
import React = require("react");
import { action, IReactionDisposer, observable, reaction } from "mobx";
import { observer } from "mobx-react";
-import { Doc } from "../../fields/Doc";
+import { Doc, HeightSym, WidthSym } from "../../fields/Doc";
import { documentSchema } from "../../fields/documentSchemas";
import { InkData, InkField, InkTool } from "../../fields/InkField";
import { makeInterface } from "../../fields/Schema";
import { BoolCast, Cast, NumCast, StrCast } from "../../fields/Types";
import { TraceMobx } from "../../fields/util";
-import { emptyFunction, returnFalse, setupMoveUpEvents } from "../../Utils";
+import { emptyFunction, returnFalse, setupMoveUpEvents, OmitKeys } from "../../Utils";
import { CognitiveServices } from "../cognitive_services/CognitiveServices";
import { CurrentUserUtils } from "../util/CurrentUserUtils";
import { InteractionUtils } from "../util/InteractionUtils";
@@ -22,6 +22,7 @@ import { InkTangentHandles } from "./InkTangentHandles";
import { FieldView, FieldViewProps } from "./nodes/FieldView";
import Color = require("color");
import { Transform } from "../util/Transform";
+import { FormattedTextBox } from "./nodes/formattedText/FormattedTextBox";
type InkDocument = makeInterface<[typeof documentSchema]>;
const InkDocument = makeInterface(documentSchema);
@@ -246,15 +247,17 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
["transparent", "rgb(68, 118, 247)", "rgb(68, 118, 247)", "yellow", "magenta", "cyan", "orange"][highlightIndex];
// Invisible polygonal line that enables the ink to be selected by the user.
const clickableLine = InteractionUtils.CreatePolyline(inkData, inkLeft, inkTop, highlightColor,
- inkStrokeWidth, inkStrokeWidth + (highlightIndex && closed && (new Color(fillColor)).alpha() < 1 ? 6 : 15),
+ inkStrokeWidth, inkStrokeWidth + (highlightIndex && closed && fillColor && (new Color(fillColor)).alpha() < 1 ? 6 : 15),
StrCast(this.layoutDoc.strokeLineJoin), StrCast(this.layoutDoc.strokeLineCap),
StrCast(this.layoutDoc.strokeBezier), !closed ? "none" : fillColor === "transparent" ? "none" : fillColor, startMarker, endMarker,
undefined, inkScaleX, inkScaleY, "", this.props.pointerEvents ?? (this.props.layerProvider?.(this.props.Document) === false ? "none" : "visiblepainted"), 0.0, false);
// Set of points rendered upon the ink that can be added if a user clicks on one.
- return (
+ return <div className="inkStroke-wrapper" style={{ display: "flex", alignItems: "center", height: "100%" }}>
<svg className="inkStroke"
style={{
+ width: "100%",
+ height: "100%",
pointerEvents: "none",
transform: this.props.Document.isInkMask ? `translate(${InkingStroke.MaskDim / 2}px, ${InkingStroke.MaskDim / 2}px)` : undefined,
mixBlendMode: this.layoutDoc.tool === InkTool.Highlighter ? "multiply" : "unset",
@@ -275,7 +278,26 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
{clickableLine}
{inkLine}
</svg>
- );
+ {!closed ? (null) :
+ <div className="inkStroke-text" style={{
+ color: StrCast(this.layoutDoc.textColor, "black"),
+ pointerEvents: this.props.isDocumentActive?.() ? "all" : undefined,
+ width: this.layoutDoc[WidthSym](),
+ }}>
+ <FormattedTextBox
+ {...OmitKeys(this.props, ['children']).omit}
+ yPadding={10}
+ xPadding={10}
+ fieldKey={"text"}
+ fontSize={12}
+ dontRegisterView={true}
+ noSidebar={true}
+ dontScale={true}
+ isContentActive={this.isContentActive}
+ />
+ </div>
+ }
+ </div>;
}
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index 9769453a0..9cc887e3d 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -153,28 +153,44 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
const atop = this.visibleY(adiv);
const btop = this.visibleY(bdiv);
if (!a.width || !b.width) return undefined;
+ const aDocBounds = (A.props as any).DocumentView?.().getBounds() || { left: 0, right: 0, top: 0, bottom: 0 };
+ const bDocBounds = (B.props as any).DocumentView?.().getBounds() || { left: 0, right: 0, top: 0, bottom: 0 };
+ const acentX = (a.left + a.right) / 2;
+ const acentY = (a.top + a.bottom) / 2;
+ const bcentX = (b.left + b.right) / 2;
+ const bcentY = (b.top + b.bottom) / 2;
+ const pt1Arc = ((acentX - aDocBounds.left) > 0.1 && (aDocBounds.right - acentX) > 0.1) ||
+ ((acentY - aDocBounds.top) > 0.1 && (aDocBounds.bottom - acentY) > 0.1);
+ const pt2Arc = ((bcentX - bDocBounds.left) > 0.1 && (bDocBounds.right - bcentX) > 0.1) ||
+ ((bcentY - bDocBounds.top) > 0.1 && (bDocBounds.bottom - bcentY) > 0.1);
const atop2 = this.visibleY(adiv);
const btop2 = this.visibleY(bdiv);
const aleft = this.visibleX(adiv);
const bleft = this.visibleX(bdiv);
const clipped = aleft !== a.left || atop !== a.top || bleft !== b.left || btop !== b.top;
- const apt = Utils.closestPtBetweenRectangles(aleft, atop, a.width, a.height, bleft, btop, b.width, b.height, a.left + a.width / 2, a.top + a.height / 2);
- const bpt = Utils.closestPtBetweenRectangles(bleft, btop, b.width, b.height, aleft, atop, a.width, a.height, apt.point.x, apt.point.y);
- const pt1 = [apt.point.x, apt.point.y];
- const pt2 = [bpt.point.x, bpt.point.y];
- const pt1vec = [pt1[0] - (aleft + a.width / 2), pt1[1] - (atop + a.height / 2)];
- const pt2vec = [pt2[0] - (bleft + b.width / 2), pt2[1] - (btop + b.height / 2)];
+ const pt1 = [aleft + a.width / 2, atop + a.height / 2];
+ const pt2 = [bleft + b.width / 2, btop + b.width / 2];
+ const pt1vec = [pt1[0] - (aDocBounds.left + aDocBounds.right) / 2, pt1[1] - (aDocBounds.top + aDocBounds.bottom) / 2];
+ const pt2vec = [pt2[0] - (bDocBounds.left + bDocBounds.right) / 2, pt2[1] - (bDocBounds.top + bDocBounds.bottom) / 2];
const pt1len = Math.sqrt((pt1vec[0] * pt1vec[0]) + (pt1vec[1] * pt1vec[1]));
const pt2len = Math.sqrt((pt2vec[0] * pt2vec[0]) + (pt2vec[1] * pt2vec[1]));
const ptlen = Math.sqrt((pt1[0] - pt2[0]) * (pt1[0] - pt2[0]) + (pt1[1] - pt2[1]) * (pt1[1] - pt2[1])) / 2;
- const pt1norm = clipped ? [0, 0] : [pt1vec[0] / pt1len * ptlen, pt1vec[1] / pt1len * ptlen];
- const pt2norm = clipped ? [0, 0] : [pt2vec[0] / pt2len * ptlen, pt2vec[1] / pt2len * ptlen];
+ const pt1norm = clipped ? [0, 0] : !pt1Arc ? [pt1vec[0] / pt1len * ptlen, pt1vec[1] / pt1len * ptlen] :
+ Math.abs(acentY - aDocBounds.top) < 0.01 ||
+ Math.abs(acentY - aDocBounds.bottom) < 0.01 ? [0, (pt2[1] - pt1[1]) / 2] : [(pt2[0] - pt1[0]) / 2, 0];
+ const pt2norm = clipped ? [0, 0] : !pt2Arc ? [pt2vec[0] / pt2len * ptlen, pt2vec[1] / pt2len * ptlen] :
+ Math.abs(bcentY - bDocBounds.top) < 0.01 ||
+ Math.abs(bcentY - bDocBounds.bottom) < 0.01 ? [0, (pt1[1] - pt2[1]) / 2] : [(pt1[0] - pt2[0]) / 2, 0];
+ const pt1normlen = Math.sqrt(pt1norm[0] * pt1norm[0] + pt1norm[1] * pt1norm[1]) || 1;
+ const pt2normlen = Math.sqrt(pt2norm[0] * pt2norm[0] + pt2norm[1] * pt2norm[1]) || 1;
+ const pt1normalized = [pt1norm[0] / pt1normlen, pt1norm[1] / pt1normlen];
+ const pt2normalized = [pt2norm[0] / pt2normlen, pt2norm[1] / pt2normlen];
const aActive = A.isSelected() || Doc.IsBrushed(A.rootDoc);
const bActive = B.isSelected() || Doc.IsBrushed(B.rootDoc);
const textX = (Math.min(pt1[0], pt2[0]) + Math.max(pt1[0], pt2[0])) / 2 + NumCast(LinkDocs[0].linkOffsetX);
const textY = (pt1[1] + pt2[1]) / 2 + NumCast(LinkDocs[0].linkOffsetY);
- return { a, b, pt1norm, pt2norm, aActive, bActive, textX, textY, pt1, pt2 };
+ return { a, b, pt1norm, pt2norm, aActive, bActive, textX, textY, pt1: [pt1[0] + pt1normalized[0] * 13, pt1[1] + pt1normalized[1] * 13], pt2: [pt2[0] + pt2normalized[0] * 13, pt2[1] + pt2normalized[1] * 13] };
}
render() {
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index d9a5f2b48..9d0402075 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1140,10 +1140,16 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
clipboardTextSerializer: this.clipboardTextSerializer,
handlePaste: this.handlePaste,
});
- const startupText = !rtfField && this._editorView && Field.toString(this.dataDoc[fieldKey] as Field);
- if (startupText) {
- const { state: { tr }, dispatch } = this._editorView;
- dispatch(tr.insertText(startupText));
+ const { state, dispatch } = this._editorView;
+ if (!rtfField) {
+ const startupText = Field.toString(this.dataDoc[fieldKey] as Field);
+ if (startupText) {
+ dispatch(state.tr.insertText(startupText));
+ } else if (!FormattedTextBox.LiveTextUndo) {
+ selectAll(this._editorView!.state, (tr) => {
+ this._editorView!.dispatch(tr.replaceSelectionWith(state.schema.nodes.paragraph.create({ align: "center" })));
+ });
+ }
}
(this._editorView as any).TextView = this;
}