111 lines
2.8 KiB
TypeScript
111 lines
2.8 KiB
TypeScript
import { useCallback } from "react";
|
|
import Konva from "konva";
|
|
import { useEditorStore } from "../../store/editorStore";
|
|
|
|
export const useSelectionHandlers = () => {
|
|
// Read live state via getState() so callbacks never go stale and can have
|
|
// empty deps — this prevents ObjectsLayer from re-rendering every time
|
|
// unrelated React state (e.g. active guide IDs) changes in EditorCanvas.
|
|
|
|
const handleSelect = useCallback((id: string, _node: Konva.Node, e?: Konva.KonvaEventObject<MouseEvent>) => {
|
|
const {
|
|
objects,
|
|
selectedObjectIds,
|
|
tool,
|
|
setTool,
|
|
setSelectedObjectId,
|
|
addToSelection,
|
|
removeFromSelection,
|
|
setSelectedTableId,
|
|
setSelectedCellId,
|
|
} = useEditorStore.getState();
|
|
|
|
if (tool !== "select") {
|
|
setTool("select");
|
|
}
|
|
|
|
const obj = objects.find((o) => o.id === id);
|
|
const isMultiSelect = e?.evt?.metaKey || e?.evt?.ctrlKey || e?.evt?.shiftKey;
|
|
|
|
if (obj?.groupId && obj.type !== "group") {
|
|
const groupObject = objects.find((o) => o.id === obj.groupId);
|
|
if (groupObject) {
|
|
if (isMultiSelect) {
|
|
if (selectedObjectIds.includes(groupObject.id)) {
|
|
removeFromSelection(groupObject.id);
|
|
} else {
|
|
addToSelection(groupObject.id);
|
|
}
|
|
} else {
|
|
setSelectedObjectId(groupObject.id);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (isMultiSelect) {
|
|
if (selectedObjectIds.includes(id)) {
|
|
removeFromSelection(id);
|
|
} else {
|
|
addToSelection(id);
|
|
}
|
|
} else {
|
|
setSelectedObjectId(id);
|
|
}
|
|
|
|
if (obj?.type === "grid") {
|
|
setSelectedTableId(id);
|
|
} else if (!isMultiSelect) {
|
|
setSelectedTableId(null);
|
|
}
|
|
|
|
if (!isMultiSelect) {
|
|
setSelectedCellId(null);
|
|
}
|
|
}, []);
|
|
|
|
const handleCellClick = useCallback((tableId: string, cellId: string, e?: Konva.KonvaEventObject<MouseEvent>) => {
|
|
const {
|
|
selectedObjectIds,
|
|
addToSelection,
|
|
removeFromSelection,
|
|
setSelectedTableId,
|
|
setSelectedObjectId,
|
|
setSelectedCellId,
|
|
} = useEditorStore.getState();
|
|
|
|
const isMultiSelect = e?.evt?.metaKey || e?.evt?.ctrlKey || e?.evt?.shiftKey;
|
|
|
|
if (isMultiSelect) {
|
|
if (selectedObjectIds.includes(tableId)) {
|
|
removeFromSelection(tableId);
|
|
} else {
|
|
addToSelection(tableId);
|
|
}
|
|
} else {
|
|
setSelectedTableId(tableId);
|
|
setSelectedObjectId(tableId);
|
|
}
|
|
|
|
setSelectedCellId(cellId);
|
|
}, []);
|
|
|
|
const handleCellDblClick = useCallback((
|
|
tableId: string,
|
|
cellId: string,
|
|
x: number,
|
|
y: number,
|
|
width: number,
|
|
height: number,
|
|
text: string,
|
|
) => {
|
|
useEditorStore.getState().setEditingCell({ tableId, cellId, x, y, width, height, value: text });
|
|
}, []);
|
|
|
|
return {
|
|
handleSelect,
|
|
handleCellClick,
|
|
handleCellDblClick,
|
|
};
|
|
};
|