diff --git a/src/components/SystemMapCanvas/InputTextArea.tsx b/src/components/SystemMapCanvas/InputTextArea.tsx index 5ca693c..2bf9e98 100644 --- a/src/components/SystemMapCanvas/InputTextArea.tsx +++ b/src/components/SystemMapCanvas/InputTextArea.tsx @@ -23,16 +23,20 @@ export const InputTextArea = ({ setValue(value0.replaceAll("\\n", "\\\n").replaceAll("\n", "\\n")); }, [value0, visible]); - function handleKeyDown(event: SyntheticEvent) { - const e = event as unknown as KeyboardEvent; - if (e.code === "Enter") { - if (value.replaceAll(" ", "").replaceAll("\n", "") === "") { - onKeyEnterDown(value0); - return; - } - onKeyEnterDown(value.replaceAll("\\n", "\n").replaceAll("\\\n", "\\n")); + useEffect(() => { + if (value.replaceAll(" ", "").replaceAll("\n", "") === "") { + onKeyEnterDown(value0); + return; + } + if (value.indexOf("\n") >= 0) { + onKeyEnterDown( + value + .replaceAll("\n", "") + .replaceAll("\\n", "\n") + .replaceAll("\\\n", "\\n"), + ); } - } + }, [value]); return ( <div @@ -43,7 +47,6 @@ export const InputTextArea = ({ <textarea placeholder="" value={value} - onKeyDown={handleKeyDown} onChange={(e) => setValue(e.target.value)} style={{ width: width, height: height, resize: "none" }} ></textarea> diff --git a/src/components/SystemMapCanvas/SystemMapCanvas.tsx b/src/components/SystemMapCanvas/SystemMapCanvas.tsx index 41bf0c6..9a1c968 100644 --- a/src/components/SystemMapCanvas/SystemMapCanvas.tsx +++ b/src/components/SystemMapCanvas/SystemMapCanvas.tsx @@ -79,6 +79,9 @@ export const SystemMapCanvas = ({ handleDoubleClick, handleClick, handleContextMenu, + handleTouchStart, + handleTouchMove, + handleTouchUp, ] = useMouse( app, ref, @@ -87,7 +90,8 @@ export const SystemMapCanvas = ({ editingText, dispatch, itemName, - handleEdit, + editTextStart, + editTextEnd, ); const [ @@ -176,13 +180,19 @@ export const SystemMapCanvas = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [state.cmdUndoReset]); - function handleEdit(item: string) { + function editTextStart(item: string) { if (isVariable(item)) { setEditingText(item); } } - function handleNameKeyEnterDown(value: string) { + function editTextEnd() { + setEditingText(""); + setSelected(""); + setInputVisible(false); + } + + function changeText(value: string) { const item = structuredClone( state.items.variables.find((variable) => variable.name === editingText), ); @@ -216,6 +226,9 @@ export const SystemMapCanvas = ({ onMouseUp={handleMouseUp} onDoubleClick={handleDoubleClick} onClick={handleClick} + onTouchStart={handleTouchStart} + onTouchMove={handleTouchMove} + onTouchEnd={handleTouchUp} ></Stage> </div> <InputTextArea @@ -224,7 +237,7 @@ export const SystemMapCanvas = ({ width={inputWidth} height={inputHeight} value0={inputValue} - onKeyEnterDown={handleNameKeyEnterDown} + onKeyEnterDown={changeText} /> </div> ); diff --git a/src/components/SystemMapCanvas/hooks/useMouse.ts b/src/components/SystemMapCanvas/hooks/useMouse.ts index 6bd4751..7fcd136 100644 --- a/src/components/SystemMapCanvas/hooks/useMouse.ts +++ b/src/components/SystemMapCanvas/hooks/useMouse.ts @@ -19,7 +19,8 @@ export function useMouse( editingText: string, dispatch: Dispatch<Actions>, itemName: (xyCanvas: Point, xyMap: Point) => string, - handleEdit: (item: string) => void, + editTextStart: (item: string) => void, + editTextEnd: () => void, ): [ () => void, () => void, @@ -29,14 +30,16 @@ export function useMouse( (event: SyntheticEvent) => void, (event: SyntheticEvent) => void, (event: SyntheticEvent) => void, + (event: SyntheticEvent) => void, + (event: SyntheticEvent) => void, + (event: SyntheticEvent) => void, ] { const [scale, setScale] = useState<Point>({ x: 1, y: 1 }); - const [editable, setEditable] = useState<boolean>(false); + const [isEditable, setIsEditable] = useState<boolean>(false); - const [moving, setMoving] = useState<boolean>(false); + const [isMouseMoved, setIsMouseMoved] = useState<boolean>(false); const [isMovingViewport, setIsMovingViewport] = useState<boolean>(false); - - const [movingViewportXY0, setMovingViewportXY0] = useState<Point>({ + const [isMovingViewportXY0, setIsMovingViewportXY0] = useState<Point>({ x: 0, y: 0, }); @@ -44,6 +47,7 @@ export function useMouse( x: 0, y: 0, }); + const [isTouched, setIsTouched] = useState<boolean>(false); const handleZoomOut = (): void => { setScale({ x: scale.x * 0.8, y: scale.y * 0.8 }); @@ -110,33 +114,25 @@ export function useMouse( }; function startMovingViewport(xyCanvas: Point) { - setMovingViewportXY0(xyCanvas); + setIsMovingViewportXY0(xyCanvas); } function moveViewport(xyCanvas: Point) { const position1 = { - x: viewportPosition.x + xyCanvas.x - movingViewportXY0.x, - y: viewportPosition.y + xyCanvas.y - movingViewportXY0.y, + x: viewportPosition.x + xyCanvas.x - isMovingViewportXY0.x, + y: viewportPosition.y + xyCanvas.y - isMovingViewportXY0.y, }; app?.stage.position.set(position1.x, position1.y); setViewportPosition(position1); - setMovingViewportXY0(xyCanvas); + setIsMovingViewportXY0(xyCanvas); } - function handleMouseDown(event: SyntheticEvent) { - setMoving(false); + function handleDown(x: number, y: number) { if (editingText !== "") { return; } - const e = event as unknown as MouseEvent; - e.stopPropagation(); - //console.log(e); - - if (e.button !== 0) { - return; - } - const [xyCanvas, xyMap] = XY(e.clientX, e.clientY); + const [xyCanvas, xyMap] = XY(x, y); const item = itemName(xyCanvas, xyMap); if (item === "") { @@ -145,27 +141,17 @@ export function useMouse( return; } - if (e.button === 0) { - dispatch({ type: "MouseLeftDown", xy: xyMap, item: item }); - } + dispatch({ type: "MouseLeftDown", xy: xyMap, item: item }); } - function handleMouseMove(event: SyntheticEvent) { + function handleMove(x: number, y: number) { setSelected(""); - setMoving(true); if (editingText !== "") { return; } - const e = event as unknown as MouseEvent; - e.stopPropagation(); - //console.log(e); - - if (e.button !== 0) { - return; - } - const [xyCanvas, xyMap] = XY(e.clientX, e.clientY); + const [xyCanvas, xyMap] = XY(x, y); const item = itemName(xyCanvas, xyMap); if (isMovingViewport) { @@ -176,10 +162,23 @@ export function useMouse( dispatch({ type: "MouseMove", xy: xyMap, item: item }); } - function handleMouseUp(event: SyntheticEvent) { + function handleUp(x: number, y: number) { if (editingText !== "") { return; } + + const [xyCanvas, xyMap] = XY(x, y); + const item = itemName(xyCanvas, xyMap); + + if (isMovingViewport) { + setIsMovingViewport(false); + return; + } + + dispatch({ type: "MouseLeftUp", xy: xyMap, item: item }); + } + + function handleMouseDown(event: SyntheticEvent) { const e = event as unknown as MouseEvent; e.stopPropagation(); //console.log(e); @@ -188,23 +187,48 @@ export function useMouse( return; } - const [xyCanvas, xyMap] = XY(e.clientX, e.clientY); - const item = itemName(xyCanvas, xyMap); + if (isTouched) { + return; + } - if (isMovingViewport) { - setIsMovingViewport(false); + setIsMouseMoved(false); + handleDown(e.clientX, e.clientY); + } + + function handleMouseMove(event: SyntheticEvent) { + const e = event as unknown as MouseEvent; + e.stopPropagation(); + //console.log(e); + + if (e.button !== 0) { return; } - dispatch({ type: "MouseLeftUp", xy: xyMap, item: item }); + if (isTouched) { + return; + } + + setIsMouseMoved(true); + handleMove(e.clientX, e.clientY); } - function handleDoubleClick(event: SyntheticEvent) { - setSelected(""); + function handleMouseUp(event: SyntheticEvent) { + const e = event as unknown as MouseEvent; + e.stopPropagation(); + //console.log(e); - if (editingText !== "") { + if (e.button !== 0) { + return; + } + + if (isTouched) { return; } + + handleUp(e.clientX, e.clientY); + } + + function handleDoubleClick(event: SyntheticEvent) { const e = event as unknown as MouseEvent; e.stopPropagation(); //console.log(e); @@ -213,6 +237,12 @@ export function useMouse( return; } + setSelected(""); + + if (editingText !== "") { + return; + } + const [xyCanvas, xyMap] = XY(e.clientX, e.clientY); const item = itemName(xyCanvas, xyMap); @@ -224,17 +254,22 @@ export function useMouse( } function handleClick(event: SyntheticEvent) { - if (moving) { + const e = event as unknown as MouseEvent; + e.stopPropagation(); + //console.log(e); + + setIsTouched(false); + + if (e.button !== 0) { return; } + if (editingText !== "") { + editTextEnd(); return; } - const e = event as unknown as MouseEvent; - e.stopPropagation(); - //console.log(e); - if (e.button !== 0) { + if (isMouseMoved) { return; } @@ -243,18 +278,18 @@ export function useMouse( if (selected !== item) { setSelected(item); - setEditable(false); + setIsEditable(false); setTimeout(() => { - setEditable(true); + setIsEditable(true); }, 1000); return; } if (selected === item) { - if (!editable) { + if (!isEditable) { return; } - handleEdit(item); + editTextStart(item); setSelected(item); } @@ -267,6 +302,45 @@ export function useMouse( e.preventDefault(); } + function handleTouchStart(event: SyntheticEvent) { + const e = event as unknown as TouchEvent; + e.stopPropagation(); + //console.log(e); + + if (e.changedTouches.length < 1) { + return; + } + + handleDown(e.changedTouches[0].clientX, e.changedTouches[0].clientY); + } + + function handleTouchMove(event: SyntheticEvent) { + const e = event as unknown as TouchEvent; + e.stopPropagation(); + //console.log(e); + + if (e.changedTouches.length < 1) { + return; + } + + handleMove(e.changedTouches[0].clientX, e.changedTouches[0].clientY); + } + + function handleTouchUp(event: SyntheticEvent) { + const e = event as unknown as TouchEvent; + e.stopPropagation(); + //console.log(e); + + setIsTouched(true); + setIsMouseMoved(false); + + if (e.changedTouches.length < 1) { + return; + } + + handleUp(e.changedTouches[0].clientX, e.changedTouches[0].clientY); + } + return [ handleZoomIn, handleZoomOut, @@ -276,5 +350,8 @@ export function useMouse( handleDoubleClick, handleClick, handleContextMenu, + handleTouchStart, + handleTouchMove, + handleTouchUp, ]; }