2020-02-03 21:52:21 +04:00
|
|
|
import { t } from "../i18n";
|
2020-04-08 09:49:52 -07:00
|
|
|
import { NonDeletedExcalidrawElement } from "../element/types";
|
2020-02-16 22:54:50 +01:00
|
|
|
import { getSelectedElements } from "../scene";
|
2020-02-03 21:52:21 +04:00
|
|
|
|
2020-03-13 15:32:47 -04:00
|
|
|
import "./HintViewer.scss";
|
2020-03-08 10:20:55 -07:00
|
|
|
import { AppState } from "../types";
|
2021-10-21 22:05:48 +02:00
|
|
|
import {
|
|
|
|
isImageElement,
|
|
|
|
isLinearElement,
|
2021-12-16 21:14:03 +05:30
|
|
|
isTextBindableContainer,
|
2021-10-21 22:05:48 +02:00
|
|
|
isTextElement,
|
|
|
|
} from "../element/typeChecks";
|
2020-06-01 11:35:44 +02:00
|
|
|
import { getShortcutKey } from "../utils";
|
2022-03-11 19:53:42 +05:30
|
|
|
import { isEraserActive } from "../appState";
|
2020-02-03 21:52:21 +04:00
|
|
|
|
2021-11-01 13:36:06 +01:00
|
|
|
interface HintViewerProps {
|
2020-03-08 10:20:55 -07:00
|
|
|
appState: AppState;
|
2020-04-08 09:49:52 -07:00
|
|
|
elements: readonly NonDeletedExcalidrawElement[];
|
2021-11-01 13:36:06 +01:00
|
|
|
isMobile: boolean;
|
2020-02-03 21:52:21 +04:00
|
|
|
}
|
|
|
|
|
2021-11-01 13:36:06 +01:00
|
|
|
const getHints = ({ appState, elements, isMobile }: HintViewerProps) => {
|
2022-03-25 20:46:01 +05:30
|
|
|
const { activeTool, isResizing, isRotating, lastPointerDownWith } = appState;
|
2020-03-08 10:20:55 -07:00
|
|
|
const multiMode = appState.multiElement !== null;
|
2021-11-01 13:36:06 +01:00
|
|
|
|
2022-04-20 14:40:03 +02:00
|
|
|
if (appState.isLibraryOpen) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2022-03-11 19:53:42 +05:30
|
|
|
if (isEraserActive(appState)) {
|
|
|
|
return t("hints.eraserRevert");
|
|
|
|
}
|
2022-03-25 20:46:01 +05:30
|
|
|
if (activeTool.type === "arrow" || activeTool.type === "line") {
|
2020-02-03 21:52:21 +04:00
|
|
|
if (!multiMode) {
|
|
|
|
return t("hints.linearElement");
|
|
|
|
}
|
|
|
|
return t("hints.linearElementMulti");
|
|
|
|
}
|
|
|
|
|
2022-03-25 20:46:01 +05:30
|
|
|
if (activeTool.type === "freedraw") {
|
2020-05-12 20:10:11 +01:00
|
|
|
return t("hints.freeDraw");
|
|
|
|
}
|
|
|
|
|
2022-03-25 20:46:01 +05:30
|
|
|
if (activeTool.type === "text") {
|
2020-08-20 22:55:44 +03:00
|
|
|
return t("hints.text");
|
|
|
|
}
|
|
|
|
|
2022-03-25 20:46:01 +05:30
|
|
|
if (appState.activeTool.type === "image" && appState.pendingImageElement) {
|
2021-10-21 22:05:48 +02:00
|
|
|
return t("hints.placeImage");
|
|
|
|
}
|
|
|
|
|
2020-04-07 17:49:59 +09:00
|
|
|
const selectedElements = getSelectedElements(elements, appState);
|
2021-11-01 13:36:06 +01:00
|
|
|
|
2020-04-07 17:49:59 +09:00
|
|
|
if (
|
|
|
|
isResizing &&
|
|
|
|
lastPointerDownWith === "mouse" &&
|
|
|
|
selectedElements.length === 1
|
|
|
|
) {
|
2020-03-17 20:55:40 +01:00
|
|
|
const targetElement = selectedElements[0];
|
2020-12-22 11:00:51 +01:00
|
|
|
if (isLinearElement(targetElement) && targetElement.points.length === 2) {
|
|
|
|
return t("hints.lockAngle");
|
2020-02-03 21:52:21 +04:00
|
|
|
}
|
2021-10-21 22:05:48 +02:00
|
|
|
return isImageElement(targetElement)
|
|
|
|
? t("hints.resizeImage")
|
|
|
|
: t("hints.resize");
|
2020-02-03 21:52:21 +04:00
|
|
|
}
|
|
|
|
|
2020-04-02 17:40:26 +09:00
|
|
|
if (isRotating && lastPointerDownWith === "mouse") {
|
|
|
|
return t("hints.rotate");
|
|
|
|
}
|
|
|
|
|
2021-12-31 11:00:20 +01:00
|
|
|
if (selectedElements.length === 1 && isTextElement(selectedElements[0])) {
|
|
|
|
return t("hints.text_selected");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (appState.editingElement && isTextElement(appState.editingElement)) {
|
|
|
|
return t("hints.text_editing");
|
|
|
|
}
|
|
|
|
|
2022-03-25 20:46:01 +05:30
|
|
|
if (activeTool.type === "selection") {
|
2021-12-31 11:00:20 +01:00
|
|
|
if (
|
|
|
|
appState.draggingElement?.type === "selection" &&
|
|
|
|
!appState.editingElement &&
|
|
|
|
!appState.editingLinearElement
|
|
|
|
) {
|
|
|
|
return t("hints.deepBoxSelect");
|
|
|
|
}
|
|
|
|
if (!selectedElements.length && !isMobile) {
|
|
|
|
return t("hints.canvasPanning");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-16 21:14:03 +05:30
|
|
|
if (selectedElements.length === 1) {
|
|
|
|
if (isLinearElement(selectedElements[0])) {
|
|
|
|
if (appState.editingLinearElement) {
|
|
|
|
return appState.editingLinearElement.selectedPointsIndices
|
|
|
|
? t("hints.lineEditor_pointSelected")
|
|
|
|
: t("hints.lineEditor_nothingSelected");
|
|
|
|
}
|
|
|
|
return t("hints.lineEditor_info");
|
|
|
|
}
|
|
|
|
if (isTextBindableContainer(selectedElements[0])) {
|
|
|
|
return t("hints.bindTextToElement");
|
2020-06-01 11:35:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-03 21:52:21 +04:00
|
|
|
return null;
|
|
|
|
};
|
|
|
|
|
2021-11-01 13:36:06 +01:00
|
|
|
export const HintViewer = ({
|
|
|
|
appState,
|
|
|
|
elements,
|
|
|
|
isMobile,
|
|
|
|
}: HintViewerProps) => {
|
2020-06-01 11:35:44 +02:00
|
|
|
let hint = getHints({
|
2020-03-08 10:20:55 -07:00
|
|
|
appState,
|
2020-02-03 21:52:21 +04:00
|
|
|
elements,
|
2021-11-01 13:36:06 +01:00
|
|
|
isMobile,
|
2020-02-03 21:52:21 +04:00
|
|
|
});
|
|
|
|
if (!hint) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2020-06-01 11:35:44 +02:00
|
|
|
hint = getShortcutKey(hint);
|
|
|
|
|
2020-03-01 14:39:03 -05:00
|
|
|
return (
|
|
|
|
<div className="HintViewer">
|
|
|
|
<span>{hint}</span>
|
|
|
|
</div>
|
|
|
|
);
|
2020-02-03 21:52:21 +04:00
|
|
|
};
|