Restore input value and fix history

Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
Mark Tolmacs 2025-03-30 16:32:47 +02:00
parent 5cc5c626df
commit 3d40221dc1
4 changed files with 79 additions and 42 deletions

View file

@ -117,6 +117,7 @@ const handleFinished: DragFinishedCallbackType<AngleProps["property"]> = ({
scene, scene,
accumulatedChange, accumulatedChange,
setAppState, setAppState,
setInputValue,
}) => { }) => {
const elementsMap = scene.getNonDeletedElementsMap(); const elementsMap = scene.getNonDeletedElementsMap();
const origElement = originalElements[0]; const origElement = originalElements[0];
@ -125,19 +126,32 @@ const handleFinished: DragFinishedCallbackType<AngleProps["property"]> = ({
const latestElement = elementsMap.get(origElement.id); const latestElement = elementsMap.get(origElement.id);
if (latestElement) { if (latestElement) {
updateBindings(latestElement, elementsMap, originalAppState.zoom, () => {
const change = degreesToRadians(accumulatedChange as Degrees);
mutateElement(latestElement, {
angle: (latestElement.angle - change) as Radians,
});
});
setAppState({ setAppState({
suggestedBindings: [], suggestedBindings: [],
}); });
const success = updateBindings(
latestElement,
elementsMap,
originalAppState.zoom,
);
if (!success) {
const change = degreesToRadians(accumulatedChange as Degrees);
const angle = (latestElement.angle - change) as Radians;
mutateElement(latestElement, {
angle,
});
setInputValue(angle);
return false;
}
} }
} }
return true;
}; };
const Angle = ({ element, scene, appState, property }: AngleProps) => { const Angle = ({ element, scene, appState, property }: AngleProps) => {

View file

@ -48,7 +48,8 @@ export type DragFinishedCallbackType<
originalAppState: AppState; originalAppState: AppState;
accumulatedChange: number; accumulatedChange: number;
setAppState: React.Component<any, AppState>["setState"]; setAppState: React.Component<any, AppState>["setState"];
}) => void; setInputValue: (value: number) => void;
}) => boolean;
interface StatsDragInputProps< interface StatsDragInputProps<
T extends StatsInputProperty, T extends StatsInputProperty,
@ -155,7 +156,7 @@ const StatsDragInput = <
setInputValue: (value) => setInputValue(String(value)), setInputValue: (value) => setInputValue(String(value)),
setAppState, setAppState,
}); });
dragFinishedCallback?.({ const commit = dragFinishedCallback?.({
originalElements: elements, originalElements: elements,
originalElementsMap, originalElementsMap,
scene, scene,
@ -163,10 +164,13 @@ const StatsDragInput = <
accumulatedChange: rounded, accumulatedChange: rounded,
property, property,
setAppState, setAppState,
setInputValue: (value) => setInputValue(String(value)),
}); });
app.syncActionResult({ if (commit) {
captureUpdate: CaptureUpdateAction.IMMEDIATELY, app.syncActionResult({
}); captureUpdate: CaptureUpdateAction.IMMEDIATELY,
});
}
} }
}; };
@ -311,21 +315,26 @@ const StatsDragInput = <
false, false,
); );
let commit = true;
if (originalElements !== null && originalElementsMap !== null) { if (originalElements !== null && originalElementsMap !== null) {
dragFinishedCallback?.({ commit =
originalElements, dragFinishedCallback?.({
originalElementsMap, originalElements,
scene, originalElementsMap,
originalAppState, scene,
property, originalAppState,
accumulatedChange, property,
setAppState, accumulatedChange,
}); setAppState,
setInputValue: (value) => setInputValue(String(value)),
}) ?? true;
} }
app.syncActionResult({ if (commit) {
captureUpdate: CaptureUpdateAction.IMMEDIATELY, app.syncActionResult({
}); captureUpdate: CaptureUpdateAction.IMMEDIATELY,
});
}
lastPointer = null; lastPointer = null;
accumulatedChange = 0; accumulatedChange = 0;

View file

@ -204,7 +204,8 @@ const handleFinished: DragFinishedCallbackType<"x" | "y"> = ({
accumulatedChange, accumulatedChange,
property, property,
setAppState, setAppState,
}) => { setInputValue,
}): boolean => {
const elementsMap = scene.getNonDeletedElementsMap(); const elementsMap = scene.getNonDeletedElementsMap();
const origElement = originalElements[0]; const origElement = originalElements[0];
@ -212,17 +213,29 @@ const handleFinished: DragFinishedCallbackType<"x" | "y"> = ({
const latestElement = elementsMap.get(origElement.id); const latestElement = elementsMap.get(origElement.id);
if (latestElement) { if (latestElement) {
updateBindings(latestElement, elementsMap, originalAppState.zoom, () => {
mutateElement(latestElement, {
[property]: latestElement[property] - accumulatedChange,
});
});
setAppState({ setAppState({
suggestedBindings: [], suggestedBindings: [],
}); });
const success = updateBindings(
latestElement,
elementsMap,
originalAppState.zoom,
);
if (!success) {
mutateElement(latestElement, {
[property]: latestElement[property] - accumulatedChange,
});
setInputValue(latestElement[property] - accumulatedChange);
}
return false;
} }
} }
return true;
}; };
const Position = ({ property, element, scene, appState }: PositionProps) => { const Position = ({ property, element, scene, appState }: PositionProps) => {

View file

@ -204,8 +204,7 @@ export const updateBindings = (
latestElement: ExcalidrawElement, latestElement: ExcalidrawElement,
elementsMap: NonDeletedSceneElementsMap, elementsMap: NonDeletedSceneElementsMap,
zoom?: AppState["zoom"], zoom?: AppState["zoom"],
bindingElementKeptOriginalBinding?: () => void, ): boolean => {
) => {
if (isBindingElement(latestElement)) { if (isBindingElement(latestElement)) {
const [start, end] = getOriginalBindingsIfStillCloseToArrowEnds( const [start, end] = getOriginalBindingsIfStillCloseToArrowEnds(
latestElement, latestElement,
@ -217,15 +216,17 @@ export const updateBindings = (
(latestElement.startBinding && start) || (latestElement.startBinding && start) ||
(latestElement.endBinding && end) (latestElement.endBinding && end)
) { ) {
bindingElementKeptOriginalBinding?.(); return false;
} else { }
if (latestElement.startBinding && !start) {
unbindLinearElement(latestElement, "start");
}
if (latestElement.endBinding && !end) { if (latestElement.startBinding && !start) {
unbindLinearElement(latestElement, "end"); unbindLinearElement(latestElement, "start");
} }
if (latestElement.endBinding && !end) {
unbindLinearElement(latestElement, "end");
} }
} }
return true;
}; };