confirm arrow on doubleclick (#949)

* confirm arrow on double click

* change hint

* fix cursor not updating on click
This commit is contained in:
David Luzar 2020-03-18 16:43:06 +01:00 committed by GitHub
parent 254a0753ff
commit b7da524538
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 95 additions and 16 deletions

View File

@ -18,12 +18,15 @@ export const actionFinalize = register({
if (appState.multiElement) {
// pen and mouse have hover
if (appState.lastPointerDownWith !== "touch") {
mutateElement(appState.multiElement, {
points: appState.multiElement.points.slice(
0,
appState.multiElement.points.length - 1,
),
});
const { points, lastCommittedPoint } = appState.multiElement;
if (
!lastCommittedPoint ||
points[points.length - 1] !== lastCommittedPoint
) {
mutateElement(appState.multiElement, {
points: appState.multiElement.points.slice(0, -1),
});
}
}
if (isInvisiblySmallElement(appState.multiElement)) {
newElements = newElements.slice(0, -1);

View File

@ -60,6 +60,16 @@ export class ActionManager implements ActionsManagerInterface {
return true;
}
executeAction(action: Action) {
const commitToHistory =
action.commitToHistory &&
action.commitToHistory(this.getAppState(), this.getElements());
this.updater(
action.perform(this.getElements(), this.getAppState(), null),
commitToHistory,
);
}
getContextMenuItems(actionFilter: ActionFilterFn = action => action) {
return Object.values(this.actions)
.filter(actionFilter)

View File

@ -92,6 +92,7 @@ import {
POINTER_BUTTON,
DRAGGING_THRESHOLD,
TEXT_TO_CENTER_SNAP_THRESHOLD,
ARROW_CONFIRM_THRESHOLD,
} from "../constants";
import { LayerUI } from "./LayerUI";
import { ScrollBars } from "../scene/types";
@ -102,6 +103,7 @@ import { unstable_batchedUpdates } from "react-dom";
import { SceneStateCallbackRemover } from "../scene/globalScene";
import { isLinearElement } from "../element/typeChecks";
import { rescalePoints } from "../points";
import { actionFinalize } from "../actions";
function withBatchedUpdates<
TFunction extends ((event: any) => void) | (() => void)
@ -1122,13 +1124,52 @@ export class App extends React.Component<any, AppState> {
);
if (this.state.multiElement) {
const { multiElement } = this.state;
const originX = multiElement.x;
const originY = multiElement.y;
const points = multiElement.points;
const { x: rx, y: ry } = multiElement;
mutateElement(multiElement, {
points: [...points.slice(0, -1), [x - originX, y - originY]],
});
const { points, lastCommittedPoint } = multiElement;
const lastPoint = points[points.length - 1];
setCursorForShape(this.state.elementType);
if (lastPoint === lastCommittedPoint) {
// if we haven't yet created a temp point and we're beyond commit-zone
// threshold, add a point
if (
distance2d(x - rx, y - ry, lastPoint[0], lastPoint[1]) >=
ARROW_CONFIRM_THRESHOLD
) {
mutateElement(multiElement, {
points: [...points, [x - rx, y - ry]],
});
} else {
document.documentElement.style.cursor = CURSOR_TYPE.POINTER;
// in this branch, we're inside the commit zone, and no uncommitted
// point exists. Thus do nothing (don't add/remove points).
}
} else {
// cursor moved inside commit zone, and there's uncommitted point,
// thus remove it
if (
points.length > 2 &&
lastCommittedPoint &&
distance2d(
x - rx,
y - ry,
lastCommittedPoint[0],
lastCommittedPoint[1],
) < ARROW_CONFIRM_THRESHOLD
) {
document.documentElement.style.cursor = CURSOR_TYPE.POINTER;
mutateElement(multiElement, {
points: points.slice(0, -1),
});
} else {
// update last uncommitted point
mutateElement(multiElement, {
points: [...points.slice(0, -1), [x - rx, y - ry]],
});
}
}
return;
}
@ -1505,16 +1546,36 @@ export class App extends React.Component<any, AppState> {
) {
if (this.state.multiElement) {
const { multiElement } = this.state;
const { x: rx, y: ry } = multiElement;
const { x: rx, y: ry, lastCommittedPoint } = multiElement;
// clicking inside commit zone → finalize arrow
if (
multiElement.points.length > 1 &&
lastCommittedPoint &&
distance2d(
x - rx,
y - ry,
lastCommittedPoint[0],
lastCommittedPoint[1],
) < ARROW_CONFIRM_THRESHOLD
) {
this.actionManager.executeAction(actionFinalize);
return;
}
this.setState(prevState => ({
selectedElementIds: {
...prevState.selectedElementIds,
[multiElement.id]: true,
},
}));
// clicking outside commit zone → update reference for last committed
// point
mutateElement(multiElement, {
points: [...multiElement.points, [x - rx, y - ry]],
lastCommittedPoint:
multiElement.points[multiElement.points.length - 1],
});
document.documentElement.style.cursor = CURSOR_TYPE.POINTER;
} else {
const element = newLinearElement({
type: this.state.elementType,

View File

@ -1,4 +1,5 @@
export const DRAGGING_THRESHOLD = 10; // 10px
export const ARROW_CONFIRM_THRESHOLD = 10; // 10px
export const ELEMENT_SHIFT_TRANSLATE_AMOUNT = 5;
export const ELEMENT_TRANSLATE_AMOUNT = 1;
export const TEXT_TO_CENTER_SNAP_THRESHOLD = 30;
@ -6,6 +7,7 @@ export const CURSOR_TYPE = {
TEXT: "text",
CROSSHAIR: "crosshair",
GRABBING: "grabbing",
POINTER: "pointer",
};
export const POINTER_BUTTON = {
MAIN: 0,

View File

@ -91,12 +91,14 @@ export function newTextElement(
export function newLinearElement(
opts: {
type: "arrow" | "line";
type: ExcalidrawLinearElement["type"];
lastCommittedPoint?: ExcalidrawLinearElement["lastCommittedPoint"];
} & ElementConstructorOpts,
): ExcalidrawLinearElement {
return {
..._newElementBase<ExcalidrawLinearElement>(opts.type, opts),
points: [],
lastCommittedPoint: opts.lastCommittedPoint || null,
};
}

View File

@ -44,6 +44,7 @@ export type ExcalidrawLinearElement = _ExcalidrawElementBase &
Readonly<{
type: "arrow" | "line";
points: Point[];
lastCommittedPoint?: Point | null;
}>;
export type PointerType = "mouse" | "pen" | "touch";

View File

@ -95,7 +95,7 @@
},
"hints": {
"linearElement": "Click to start multiple points, drag for single line",
"linearElementMulti": "Press Escape or Enter to finish",
"linearElementMulti": "Click on last point or press Escape or Enter to finish",
"resize": "You can constraint proportions by holding SHIFT while resizing"
},
"errorSplash": {