aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2021-09-10 10:14:04 -0400
committerbobzel <zzzman@gmail.com>2021-09-10 10:14:04 -0400
commitc9c9d00b581bc7f80edbf7848a8ffb3a8e64f005 (patch)
tree39cd429507e872efa3675de098155e6d76fe5000
parentd9419c89ccdac7435c87b27a55486b7a5980ae29 (diff)
event handling fixes for ink. double click on deselected ink takes shows handles. lightbox view works. transparent fills are not selectable.
-rw-r--r--src/client/util/InteractionUtils.tsx2
-rw-r--r--src/client/views/InkingStroke.tsx48
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx1
-rw-r--r--src/client/views/nodes/DocumentView.tsx8
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx3
5 files changed, 41 insertions, 21 deletions
diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx
index e009fb3a9..8429a806a 100644
--- a/src/client/util/InteractionUtils.tsx
+++ b/src/client/util/InteractionUtils.tsx
@@ -209,7 +209,7 @@ export namespace InteractionUtils {
points={strpts}
style={{
// filter: drawHalo ? "url(#inkSelectionHalo)" : undefined,
- fill: fill ? fill : "none",
+ fill: fill && fill !== "transparent" ? fill : "none",
opacity: 1.0,
// opacity: strokeWidth !== width ? 0.5 : undefined,
pointerEvents: pevents as any,
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index db09849fd..dc2a5b39b 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -1,26 +1,26 @@
import React = require("react");
-import { action, observable } from "mobx";
+import { action, IReactionDisposer, observable, reaction } from "mobx";
import { observer } from "mobx-react";
import { Doc } from "../../fields/Doc";
import { documentSchema } from "../../fields/documentSchemas";
import { InkData, InkField, InkTool } from "../../fields/InkField";
import { makeInterface } from "../../fields/Schema";
-import { Cast, StrCast, NumCast } from "../../fields/Types";
+import { Cast, NumCast, StrCast } from "../../fields/Types";
import { TraceMobx } from "../../fields/util";
-import { setupMoveUpEvents, emptyFunction, returnFalse } from "../../Utils";
+import { emptyFunction, returnFalse, setupMoveUpEvents } from "../../Utils";
import { CognitiveServices } from "../cognitive_services/CognitiveServices";
+import { CurrentUserUtils } from "../util/CurrentUserUtils";
import { InteractionUtils } from "../util/InteractionUtils";
import { Scripting } from "../util/Scripting";
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 { GestureOverlay } from "./GestureOverlay";
+import { Colors } from "./global/globalEnums";
import { InkControls } from "./InkControls";
import { InkHandles } from "./InkHandles";
-import { Colors } from "./global/globalEnums";
-import { GestureOverlay } from "./GestureOverlay";
+import "./InkStroke.scss";
+import { InkStrokeProperties } from "./InkStrokeProperties";
+import { FieldView, FieldViewProps } from "./nodes/FieldView";
type InkDocument = makeInterface<[typeof documentSchema]>;
const InkDocument = makeInterface(documentSchema);
@@ -29,6 +29,8 @@ const InkDocument = makeInterface(documentSchema);
export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocument>(InkDocument) {
static readonly MaskDim = 50000;
@observable private _properties?: InkStrokeProperties;
+ _handledClick = false; // flag denoting whether ink stroke has handled a psuedo-click onPointerUp so that the real onClick event can be stopPropagated
+ _selDisposer: IReactionDisposer | undefined;
constructor(props: FieldViewProps & InkDocument) {
super(props);
@@ -36,6 +38,14 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
this._properties = InkStrokeProperties.Instance;
}
+ componentDidMount() {
+ this._selDisposer = reaction(() => this.props.isSelected(), // react to stroke being deselected by turning off ink handles
+ selected => !selected && this.toggleControlButton());
+ }
+ componentWillUnmount() {
+ this._selDisposer?.();
+ }
+
public static LayoutString(fieldStr: string) {
return FieldView.LayoutString(InkingStroke, fieldStr);
}
@@ -53,14 +63,26 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
inkDoc._stayInCollection = inkDoc.isInkMask ? true : undefined;
});
+ onClick = (e: React.MouseEvent) => {
+ if (this._handledClick) {
+ e.stopPropagation(); //stop the event so that docView won't open the lightbox
+ }
+ }
+
/**
* Handles the movement of the entire ink object when the user clicks and drags.
*/
onPointerDown = (e: React.PointerEvent) => {
+ this._handledClick = false;
if (this.props.isSelected(true)) {
setupMoveUpEvents(this, e, returnFalse, emptyFunction,
- action((e: PointerEvent, doubleTap: boolean | undefined) =>
- doubleTap && this._properties && (this._properties._controlButton = true))
+ action((e: PointerEvent, doubleTap: boolean | undefined) => {
+ doubleTap = doubleTap || this.props.docViewPath().lastElement()?.docView?._pendingDoubleClick;
+ if (doubleTap && this._properties) {
+ this._properties._controlButton = true;
+ this._handledClick = true; // mark the double-click pseudo pointerevent so we can block the real mouse event from propagating to DocumentView
+ }
+ }), this._properties?._controlButton, this._properties?._controlButton
);
}
}
@@ -77,7 +99,6 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
render() {
TraceMobx();
- this.toggleControlButton();
// Extracting the ink data and formatting information of the current ink stroke.
// console.log(InkingStroke.InkShape);
const InkShape = GestureOverlay.Instance.InkShape;
@@ -115,12 +136,13 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
return (
<svg className="inkStroke"
style={{
- pointerEvents: this.props.Document.isInkMask && this.props.layerProvider?.(this.props.Document) !== false ? "all" : "none",
+ 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",
overflow: "visible",
}}
onPointerDown={this.onPointerDown}
+ onClick={this.onClick}
onContextMenu={() => {
const cm = ContextMenu.Instance;
if (cm) {
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index fad905d6d..dbab5e762 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -113,7 +113,6 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & Fo
scaling?: () => number,
setHeight: (height: number) => void,
layoutKey: string,
- hideOnLeave?: boolean,
}> {
@computed get layout(): string {
TraceMobx();
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 8b19fb204..a2d2f17b6 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -808,7 +808,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
</div>;
return <div className="documentView-contentsView"
style={{
- pointerEvents: (this.props.contentPointerEvents as any) || (this.isContentActive() ? "all" : "none"),
+ pointerEvents: this.rootDoc.type !== DocumentType.INK && ((this.props.contentPointerEvents as any) || (this.isContentActive())) ? "all" : "none",
height: this.headerMargin ? `calc(100% - ${this.headerMargin}px)` : undefined,
}}>
<DocumentContentsView key={1} {...this.props}
@@ -943,13 +943,13 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
const showTitleHover = this.ShowTitle?.includes(":hover");
const showCaption = !this.props.hideCaptions && this.Document._viewType !== CollectionViewType.Carousel ? StrCast(this.layoutDoc._showCaption) : undefined;
const captionView = !showCaption ? (null) :
- <div className="documentView-captionWrapper">
+ <div className="documentView-captionWrapper"
+ style={{ pointerEvents: this.onClickHandler || this.Document.ignoreClick ? "none" : this.isContentActive() || this.props.isDocumentActive?.() ? "all" : undefined, }}>
<FormattedTextBox {...OmitKeys(this.props, ['children']).omit}
yPadding={10}
xPadding={10}
fieldKey={showCaption}
fontSize={Math.min(32, 12 * this.props.ScreenToLocalTransform().Scale)}
- hideOnLeave={true}
styleProvider={this.captionStyleProvider}
dontRegisterView={true}
isContentActive={this.isContentActive}
@@ -964,7 +964,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
height: this.titleHeight,
color: lightOrDark(background),
background,
- pointerEvents: this.onClickHandler || this.Document.ignoreClick ? "none" : undefined,
+ pointerEvents: this.onClickHandler || this.Document.ignoreClick ? "none" : this.isContentActive() || this.props.isDocumentActive?.() ? "all" : undefined,
}}>
<EditableView ref={this._titleRef}
contents={showTitle.split(";").map(field => field.trim()).map(field => targetDoc[field]?.toString()).join("\\")}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 78de1fd89..e7a44f113 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -69,7 +69,6 @@ const translateGoogleApi = require("translate-google-api");
export interface FormattedTextBoxProps {
makeLink?: () => Opt<Doc>; // bcz: hack: notifies the text document when the container has made a link. allows the text doc to react and setup a hyeprlink for any selected text
- hideOnLeave?: boolean; // used by DocumentView for setting caption's hide on leave (bcz: would prefer to have caption-hideOnLeave field set or something similar)
xPadding?: number; // used to override document's settings for xMargin --- see CollectionCarouselView
yPadding?: number;
noSidebar?: boolean;
@@ -1558,7 +1557,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
TraceMobx();
const selected = this.props.isSelected();
const active = this.props.isContentActive();
- const scale = this.props.hideOnLeave ? 1 : (this.props.scaling?.() || 1) * NumCast(this.layoutDoc._viewScale, 1);
+ const scale = (this.props.scaling?.() || 1) * NumCast(this.layoutDoc._viewScale, 1);
const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : "";
const interactive = (CurrentUserUtils.SelectedTool === InkTool.None || SnappingManager.GetIsDragging()) && (this.layoutDoc.z || this.props.layerProvider?.(this.layoutDoc) !== false);
if (!selected && FormattedTextBoxComment.textBox === this) setTimeout(FormattedTextBoxComment.Hide);