mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
limit which linear elements can be switched
This commit is contained in:
parent
beb0bd1528
commit
8e9e0e2709
2 changed files with 48 additions and 14 deletions
|
@ -379,8 +379,29 @@ export const getSwitchableTypeFromElements = (
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onlyLinear) {
|
if (onlyLinear) {
|
||||||
|
// check at least some linear element is switchable
|
||||||
|
// for a linear to be swtichable:
|
||||||
|
// - no labels
|
||||||
|
// - not bound to anything
|
||||||
|
|
||||||
|
let linear = true;
|
||||||
|
|
||||||
|
for (const element of elements) {
|
||||||
|
if (
|
||||||
|
isArrowElement(element) &&
|
||||||
|
(element.startBinding !== null || element.endBinding !== null)
|
||||||
|
) {
|
||||||
|
linear = false;
|
||||||
|
} else if (element.boundElements && element.boundElements.length > 0) {
|
||||||
|
linear = false;
|
||||||
|
} else {
|
||||||
|
linear = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
linear: true,
|
linear,
|
||||||
generic: false,
|
generic: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { pointFrom, pointRotateRads } from "@excalidraw/math";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getSwitchableTypeFromElements,
|
getSwitchableTypeFromElements,
|
||||||
|
isArrowElement,
|
||||||
isUsingAdaptiveRadius,
|
isUsingAdaptiveRadius,
|
||||||
} from "@excalidraw/element/typeChecks";
|
} from "@excalidraw/element/typeChecks";
|
||||||
import {
|
import {
|
||||||
|
@ -223,13 +224,14 @@ const Panel = ({
|
||||||
const { generic, linear } = getSwitchableTypeFromElements(elements);
|
const { generic, linear } = getSwitchableTypeFromElements(elements);
|
||||||
|
|
||||||
const genericElements = generic ? getGenericSwitchableElements(elements) : [];
|
const genericElements = generic ? getGenericSwitchableElements(elements) : [];
|
||||||
|
const linearElements = linear ? getLinearSwitchableElements(elements) : [];
|
||||||
|
|
||||||
const sameType = generic
|
const sameType = generic
|
||||||
? genericElements.every(
|
? genericElements.every(
|
||||||
(element) => element.type === genericElements[0].type,
|
(element) => element.type === genericElements[0].type,
|
||||||
)
|
)
|
||||||
: linear
|
: linear
|
||||||
? elements.every((element) => element.type === elements[0].type)
|
? linearElements.every((element) => element.type === linearElements[0].type)
|
||||||
: false;
|
: false;
|
||||||
|
|
||||||
if (elements.length === 1) {
|
if (elements.length === 1) {
|
||||||
|
@ -289,7 +291,7 @@ const Panel = ({
|
||||||
const isSelected =
|
const isSelected =
|
||||||
sameType &&
|
sameType &&
|
||||||
((generic && genericElements[0].type === type) ||
|
((generic && genericElements[0].type === type) ||
|
||||||
(linear && elements[0].type === type));
|
(linear && linearElements[0].type === type));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ToolButton
|
<ToolButton
|
||||||
|
@ -303,11 +305,6 @@ const Panel = ({
|
||||||
keyBindingLabel={""}
|
keyBindingLabel={""}
|
||||||
aria-label={type}
|
aria-label={type}
|
||||||
data-testid={`toolbar-${type}`}
|
data-testid={`toolbar-${type}`}
|
||||||
onPointerDown={({ pointerType }) => {
|
|
||||||
if (!app.state.penDetected && pointerType === "pen") {
|
|
||||||
app.togglePenMode(true);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onChange={() => {
|
onChange={() => {
|
||||||
if (app.state.activeTool.type !== type) {
|
if (app.state.activeTool.type !== type) {
|
||||||
trackEvent("shape-switch", type, "ui");
|
trackEvent("shape-switch", type, "ui");
|
||||||
|
@ -487,11 +484,16 @@ export const switchShapes = (
|
||||||
}
|
}
|
||||||
|
|
||||||
if (linear) {
|
if (linear) {
|
||||||
const sameType = selectedElements.every(
|
const selectedLinearSwitchableElements =
|
||||||
(element) => element.type === selectedElements[0].type,
|
getLinearSwitchableElements(selectedElements);
|
||||||
|
|
||||||
|
const sameType = selectedLinearSwitchableElements.every(
|
||||||
|
(element) => element.type === selectedLinearSwitchableElements[0].type,
|
||||||
);
|
);
|
||||||
const index = sameType
|
const index = sameType
|
||||||
? LINEAR_SWITCHABLE_SHAPES.indexOf(selectedElements[0].type)
|
? LINEAR_SWITCHABLE_SHAPES.indexOf(
|
||||||
|
selectedLinearSwitchableElements[0].type,
|
||||||
|
)
|
||||||
: -1;
|
: -1;
|
||||||
nextType =
|
nextType =
|
||||||
nextType ??
|
nextType ??
|
||||||
|
@ -500,7 +502,7 @@ export const switchShapes = (
|
||||||
LINEAR_SWITCHABLE_SHAPES.length
|
LINEAR_SWITCHABLE_SHAPES.length
|
||||||
] as LinearSwitchableToolType);
|
] as LinearSwitchableToolType);
|
||||||
|
|
||||||
selectedElements.forEach((element) => {
|
selectedLinearSwitchableElements.forEach((element) => {
|
||||||
ShapeCache.delete(element);
|
ShapeCache.delete(element);
|
||||||
|
|
||||||
mutateElement(
|
mutateElement(
|
||||||
|
@ -513,12 +515,12 @@ export const switchShapes = (
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
const firstElement = selectedElements[0];
|
const firstElement = selectedLinearSwitchableElements[0];
|
||||||
|
|
||||||
app.setState((prevState) => ({
|
app.setState((prevState) => ({
|
||||||
selectedElementIds,
|
selectedElementIds,
|
||||||
selectedLinearElement:
|
selectedLinearElement:
|
||||||
selectedElements.length === 1
|
selectedLinearSwitchableElements.length === 1
|
||||||
? new LinearElementEditor(firstElement as ExcalidrawLinearElement)
|
? new LinearElementEditor(firstElement as ExcalidrawLinearElement)
|
||||||
: null,
|
: null,
|
||||||
activeTool: updateActiveTool(prevState, {
|
activeTool: updateActiveTool(prevState, {
|
||||||
|
@ -535,4 +537,15 @@ const getGenericSwitchableElements = (elements: ExcalidrawElement[]) =>
|
||||||
GENERIC_SWITCHABLE_SHAPES.includes(element.type),
|
GENERIC_SWITCHABLE_SHAPES.includes(element.type),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const getLinearSwitchableElements = (elements: ExcalidrawElement[]) =>
|
||||||
|
elements.filter(
|
||||||
|
(element) =>
|
||||||
|
LINEAR_SWITCHABLE_SHAPES.includes(element.type) &&
|
||||||
|
!(
|
||||||
|
isArrowElement(element) &&
|
||||||
|
(element.startBinding !== null || element.endBinding !== null)
|
||||||
|
) &&
|
||||||
|
(!element.boundElements || element.boundElements.length === 0),
|
||||||
|
);
|
||||||
|
|
||||||
export default ShapeSwitch;
|
export default ShapeSwitch;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue