switch different types altogether

This commit is contained in:
Ryan Di 2025-03-24 12:07:57 +11:00
parent 41a4dadaaf
commit aa9139ad78
3 changed files with 53 additions and 38 deletions

View file

@ -193,9 +193,9 @@ import {
isElbowArrow,
isFlowchartNodeElement,
isBindableElement,
isGenericSwitchableElement,
areGenericSwitchableElements,
isGenericSwitchableToolType,
isLinearSwitchableElement,
areLinearSwitchableElements,
isLinearSwitchableToolType,
} from "../element/typeChecks";
import { getCenter, getDistance } from "../gesture";
@ -4110,8 +4110,9 @@ class App extends React.Component<AppProps, AppState> {
return;
}
const genericSwitchable = isGenericSwitchableElement(selectedElements);
const linearSwitchable = isLinearSwitchableElement(selectedElements);
const genericSwitchable =
areGenericSwitchableElements(selectedElements);
const linearSwitchable = areLinearSwitchableElements(selectedElements);
if (genericSwitchable || linearSwitchable) {
const firstElement = selectedElements[0];
@ -4122,21 +4123,31 @@ class App extends React.Component<AppProps, AppState> {
event.preventDefault();
if (editorJotaiStore.get(shapeSwitchAtom)?.type === "panel") {
const index = genericSwitchable
? GENERIC_SWITCHABLE_SHAPES.indexOf(selectedElements[0].type)
: LINEAR_SWITCHABLE_SHAPES.indexOf(selectedElements[0].type);
const sameType = selectedElements.every(
(element) => element.type === selectedElements[0].type,
);
const nextType = (
genericSwitchable
? GENERIC_SWITCHABLE_SHAPES[
(index + 1) % GENERIC_SWITCHABLE_SHAPES.length
]
: LINEAR_SWITCHABLE_SHAPES[
(index + 1) % LINEAR_SWITCHABLE_SHAPES.length
]
) as ToolType;
let nextType;
this.setActiveTool({ type: nextType });
if (genericSwitchable) {
const index = sameType
? GENERIC_SWITCHABLE_SHAPES.indexOf(selectedElements[0].type)
: -1;
nextType = GENERIC_SWITCHABLE_SHAPES[
(index + 1) % GENERIC_SWITCHABLE_SHAPES.length
] as ToolType;
this.setActiveTool({ type: nextType });
} else if (linearSwitchable) {
const index = sameType
? LINEAR_SWITCHABLE_SHAPES.indexOf(selectedElements[0].type)
: -1;
nextType = LINEAR_SWITCHABLE_SHAPES[
(index + 1) % LINEAR_SWITCHABLE_SHAPES.length
] as ToolType;
this.setActiveTool({ type: nextType });
}
}
editorJotaiStore.set(shapeSwitchAtom, {
@ -4827,7 +4838,7 @@ class App extends React.Component<AppProps, AppState> {
);
if (
isGenericSwitchableElement(selectedElements) &&
areGenericSwitchableElements(selectedElements) &&
isGenericSwitchableToolType(tool.type)
) {
selectedElements.forEach((element) => {
@ -4889,7 +4900,7 @@ class App extends React.Component<AppProps, AppState> {
}
if (
isLinearSwitchableElement(selectedElements) &&
areLinearSwitchableElements(selectedElements) &&
isLinearSwitchableToolType(tool.type)
) {
selectedElements.forEach((element) => {

View file

@ -192,6 +192,10 @@ const Panel = ({
let [x1, y2, cx, cy] = [0, 0, 0, 0];
let rotatedBottomLeft = [0, 0];
const sameType = elements.every(
(element) => element.type === elements[0].type,
);
if (elements.length === 1) {
[x1, , , y2, cx, cy] = getElementAbsoluteCoords(
elements[0],
@ -245,17 +249,18 @@ const Panel = ({
>
{SHAPES.map(([type, shortcut, icon]) => {
const isSelected =
type === elements[0].type ||
(isArrowElement(elements[0]) &&
elements[0].elbowed &&
type === "elbow") ||
(isArrowElement(elements[0]) &&
elements[0].roundness &&
type === "curve") ||
(isArrowElement(elements[0]) &&
!elements[0].elbowed &&
!elements[0].roundness &&
type === "straight");
sameType &&
(type === elements[0].type ||
(isArrowElement(elements[0]) &&
elements[0].elbowed &&
type === "elbow") ||
(isArrowElement(elements[0]) &&
elements[0].roundness &&
type === "curve") ||
(isArrowElement(elements[0]) &&
!elements[0].elbowed &&
!elements[0].roundness &&
type === "straight"));
return (
<ToolButton

View file

@ -350,18 +350,17 @@ type ExcalidrawGenericSwitchableElement =
| ExcalidrawEllipseElement
| ExcalidrawDiamondElement;
export const isGenericSwitchableElement = (
export const areGenericSwitchableElements = (
elements: ExcalidrawElement[],
): elements is NonEmptyArray<ExcalidrawGenericSwitchableElement> => {
if (elements.length === 0) {
return false;
}
const firstType = elements[0].type;
return (
(firstType === "rectangle" ||
firstType === "ellipse" ||
firstType === "diamond") &&
elements.every((element) => element.type === firstType)
return elements.every(
(element) =>
element.type === "rectangle" ||
element.type === "ellipse" ||
element.type === "diamond",
);
};
@ -371,7 +370,7 @@ export const isGenericSwitchableToolType = (
return type === "rectangle" || type === "ellipse" || type === "diamond";
};
export const isLinearSwitchableElement = (
export const areLinearSwitchableElements = (
elements: ExcalidrawElement[],
): elements is NonEmptyArray<ExcalidrawLinearElement> => {
if (elements.length === 0) {