2020-02-24 15:21:13 +01:00
|
|
|
import {
|
|
|
|
isTextElement,
|
|
|
|
isExcalidrawElement,
|
|
|
|
redrawTextBoundingBox,
|
|
|
|
} from "../element";
|
2020-12-01 23:36:06 +02:00
|
|
|
import { CODES, KEYS } from "../keys";
|
2021-01-15 20:32:46 +05:30
|
|
|
import { t } from "../i18n";
|
2020-06-25 21:21:27 +02:00
|
|
|
import { register } from "./register";
|
2022-06-14 16:27:41 +05:30
|
|
|
import { newElementWith } from "../element/mutateElement";
|
2020-05-27 15:14:50 +02:00
|
|
|
import {
|
|
|
|
DEFAULT_FONT_SIZE,
|
|
|
|
DEFAULT_FONT_FAMILY,
|
|
|
|
DEFAULT_TEXT_ALIGN,
|
2020-06-25 21:21:27 +02:00
|
|
|
} from "../constants";
|
2022-06-14 19:42:49 +05:30
|
|
|
import { getBoundTextElement } from "../element/textElement";
|
2022-12-10 20:12:09 +08:00
|
|
|
import {
|
|
|
|
hasBoundTextElement,
|
|
|
|
canApplyRoundnessTypeToElement,
|
|
|
|
getDefaultRoundnessTypeForElement,
|
|
|
|
} from "../element/typeChecks";
|
2022-06-14 19:42:49 +05:30
|
|
|
import { getSelectedElements } from "../scene";
|
2020-01-12 02:22:03 +04:00
|
|
|
|
2020-07-26 16:29:44 +05:00
|
|
|
// `copiedStyles` is exported only for tests.
|
|
|
|
export let copiedStyles: string = "{}";
|
2020-01-12 02:22:03 +04:00
|
|
|
|
2020-03-07 10:20:38 -05:00
|
|
|
export const actionCopyStyles = register({
|
2020-01-12 02:22:03 +04:00
|
|
|
name: "copyStyles",
|
2022-03-28 14:46:40 +02:00
|
|
|
trackEvent: { category: "element" },
|
2020-03-08 10:20:55 -07:00
|
|
|
perform: (elements, appState) => {
|
2022-06-14 19:42:49 +05:30
|
|
|
const elementsCopied = [];
|
2020-03-23 13:05:07 +02:00
|
|
|
const element = elements.find((el) => appState.selectedElementIds[el.id]);
|
2022-06-14 19:42:49 +05:30
|
|
|
elementsCopied.push(element);
|
|
|
|
if (element && hasBoundTextElement(element)) {
|
|
|
|
const boundTextElement = getBoundTextElement(element);
|
|
|
|
elementsCopied.push(boundTextElement);
|
|
|
|
}
|
2020-01-12 02:22:03 +04:00
|
|
|
if (element) {
|
2022-06-14 19:42:49 +05:30
|
|
|
copiedStyles = JSON.stringify(elementsCopied);
|
2020-01-12 02:22:03 +04:00
|
|
|
}
|
2020-03-19 14:51:05 +01:00
|
|
|
return {
|
2021-01-15 20:32:46 +05:30
|
|
|
appState: {
|
|
|
|
...appState,
|
2022-07-11 18:11:13 +05:30
|
|
|
toast: { message: t("toast.copyStyles") },
|
2021-01-15 20:32:46 +05:30
|
|
|
},
|
2020-03-19 14:51:05 +01:00
|
|
|
commitToHistory: false,
|
|
|
|
};
|
2020-01-12 02:22:03 +04:00
|
|
|
},
|
2020-01-21 01:14:10 +02:00
|
|
|
contextItemLabel: "labels.copyStyles",
|
2020-03-23 13:05:07 +02:00
|
|
|
keyTest: (event) =>
|
2020-12-01 23:36:06 +02:00
|
|
|
event[KEYS.CTRL_OR_CMD] && event.altKey && event.code === CODES.C,
|
2020-03-07 10:20:38 -05:00
|
|
|
});
|
2020-01-12 02:22:03 +04:00
|
|
|
|
2020-03-07 10:20:38 -05:00
|
|
|
export const actionPasteStyles = register({
|
2020-01-12 02:22:03 +04:00
|
|
|
name: "pasteStyles",
|
2022-03-28 14:46:40 +02:00
|
|
|
trackEvent: { category: "element" },
|
2020-03-08 10:20:55 -07:00
|
|
|
perform: (elements, appState) => {
|
2022-06-14 19:42:49 +05:30
|
|
|
const elementsCopied = JSON.parse(copiedStyles);
|
|
|
|
const pastedElement = elementsCopied[0];
|
|
|
|
const boundTextElement = elementsCopied[1];
|
2020-02-24 15:21:13 +01:00
|
|
|
if (!isExcalidrawElement(pastedElement)) {
|
2020-03-19 14:51:05 +01:00
|
|
|
return { elements, commitToHistory: false };
|
2020-02-24 15:21:13 +01:00
|
|
|
}
|
2022-06-14 19:42:49 +05:30
|
|
|
|
|
|
|
const selectedElements = getSelectedElements(elements, appState, true);
|
|
|
|
const selectedElementIds = selectedElements.map((element) => element.id);
|
2020-01-12 02:22:03 +04:00
|
|
|
return {
|
2020-03-23 13:05:07 +02:00
|
|
|
elements: elements.map((element) => {
|
2022-06-14 19:42:49 +05:30
|
|
|
if (selectedElementIds.includes(element.id)) {
|
|
|
|
let elementStylesToCopyFrom = pastedElement;
|
|
|
|
if (isTextElement(element) && element.containerId) {
|
|
|
|
elementStylesToCopyFrom = boundTextElement;
|
|
|
|
}
|
|
|
|
if (!elementStylesToCopyFrom) {
|
|
|
|
return element;
|
|
|
|
}
|
2022-06-14 16:27:41 +05:30
|
|
|
let newElement = newElementWith(element, {
|
2022-06-14 19:42:49 +05:30
|
|
|
backgroundColor: elementStylesToCopyFrom?.backgroundColor,
|
|
|
|
strokeWidth: elementStylesToCopyFrom?.strokeWidth,
|
|
|
|
strokeColor: elementStylesToCopyFrom?.strokeColor,
|
|
|
|
strokeStyle: elementStylesToCopyFrom?.strokeStyle,
|
|
|
|
fillStyle: elementStylesToCopyFrom?.fillStyle,
|
|
|
|
opacity: elementStylesToCopyFrom?.opacity,
|
|
|
|
roughness: elementStylesToCopyFrom?.roughness,
|
2022-12-10 20:12:09 +08:00
|
|
|
roundness: elementStylesToCopyFrom.roundness
|
|
|
|
? canApplyRoundnessTypeToElement(
|
|
|
|
elementStylesToCopyFrom.roundness.type,
|
|
|
|
element,
|
|
|
|
)
|
|
|
|
? elementStylesToCopyFrom.roundness
|
|
|
|
: getDefaultRoundnessTypeForElement(element)
|
|
|
|
: null,
|
2020-03-10 20:11:02 -07:00
|
|
|
});
|
2022-06-14 16:27:41 +05:30
|
|
|
|
|
|
|
if (isTextElement(newElement)) {
|
|
|
|
newElement = newElementWith(newElement, {
|
2022-06-14 19:42:49 +05:30
|
|
|
fontSize: elementStylesToCopyFrom?.fontSize || DEFAULT_FONT_SIZE,
|
|
|
|
fontFamily:
|
|
|
|
elementStylesToCopyFrom?.fontFamily || DEFAULT_FONT_FAMILY,
|
|
|
|
textAlign:
|
|
|
|
elementStylesToCopyFrom?.textAlign || DEFAULT_TEXT_ALIGN,
|
2020-03-09 22:34:50 -07:00
|
|
|
});
|
2022-06-14 19:42:49 +05:30
|
|
|
let container = null;
|
|
|
|
if (newElement.containerId) {
|
|
|
|
container =
|
|
|
|
selectedElements.find(
|
|
|
|
(element) =>
|
|
|
|
isTextElement(newElement) &&
|
|
|
|
element.id === newElement.containerId,
|
|
|
|
) || null;
|
|
|
|
}
|
|
|
|
redrawTextBoundingBox(newElement, container);
|
2020-01-12 02:22:03 +04:00
|
|
|
}
|
2022-06-14 16:27:41 +05:30
|
|
|
|
|
|
|
if (newElement.type === "arrow") {
|
|
|
|
newElement = newElementWith(newElement, {
|
2022-06-14 19:42:49 +05:30
|
|
|
startArrowhead: elementStylesToCopyFrom.startArrowhead,
|
|
|
|
endArrowhead: elementStylesToCopyFrom.endArrowhead,
|
2022-06-14 16:27:41 +05:30
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-01-12 02:22:03 +04:00
|
|
|
return newElement;
|
|
|
|
}
|
|
|
|
return element;
|
2020-01-24 12:04:54 +02:00
|
|
|
}),
|
2020-03-19 14:51:05 +01:00
|
|
|
commitToHistory: true,
|
2020-01-12 02:22:03 +04:00
|
|
|
};
|
|
|
|
},
|
2020-01-21 01:14:10 +02:00
|
|
|
contextItemLabel: "labels.pasteStyles",
|
2020-03-23 13:05:07 +02:00
|
|
|
keyTest: (event) =>
|
2020-12-01 23:36:06 +02:00
|
|
|
event[KEYS.CTRL_OR_CMD] && event.altKey && event.code === CODES.V,
|
2020-03-07 10:20:38 -05:00
|
|
|
});
|