dev #826
@ -1,5 +1,5 @@
|
||||
'use client'
|
||||
import { useEffect } from 'react'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import '@/styles/contents.scss'
|
||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||
import { contextMenuListState, contextMenuState } from '@/store/contextMenu'
|
||||
@ -15,8 +15,13 @@ export default function QContextMenu(props) {
|
||||
const contextMenuList = useRecoilValue(contextMenuListState)
|
||||
const currentObject = useRecoilValue(currentObjectState)
|
||||
const { tempGridMode, setTempGridMode } = useTempGrid()
|
||||
const { handleKeyup } = useContextMenu()
|
||||
const { handleKeyup, triggerDelete } = useContextMenu()
|
||||
const { addDocumentEventListener, removeDocumentEvent } = useEvent()
|
||||
// [TMP-DEL 2026-05-07] 객체 선택 시 Del 키 활성화: 항상 최신 함수 참조용 ref
|
||||
const handleKeyupRef = useRef(handleKeyup)
|
||||
handleKeyupRef.current = handleKeyup
|
||||
const triggerDeleteRef = useRef(triggerDelete)
|
||||
triggerDeleteRef.current = triggerDelete
|
||||
// const { addDocumentEventListener, removeDocumentEvent } = useContext(EventContext)
|
||||
|
||||
const getYPosition = (e) => {
|
||||
@ -39,7 +44,7 @@ export default function QContextMenu(props) {
|
||||
y: window.innerHeight / 2 < e.pageY ? getYPosition(e) : e.pageY,
|
||||
}
|
||||
setContextMenu({ visible: true, ...position, currentMousePos: canvasProps.getPointer(e) })
|
||||
addDocumentEventListener('keyup', document, handleKeyup)
|
||||
// [TMP-DEL 2026-05-07] keyup 등록은 객체 선택 useEffect 가 담당. 메뉴 오픈 시 별도 등록 불필요.
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,7 +57,7 @@ export default function QContextMenu(props) {
|
||||
// e.preventDefault()
|
||||
if (contextMenu.visible) {
|
||||
setContextMenu({ ...contextMenu, visible: false })
|
||||
removeDocumentEvent('keyup')
|
||||
// [TMP-DEL 2026-05-07] 메뉴 닫혀도 객체 선택 상태면 Del 살려야 하므로 keyup 제거하지 않음
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,13 +69,33 @@ export default function QContextMenu(props) {
|
||||
document.addEventListener('click', handleOutsideClick)
|
||||
|
||||
return () => {
|
||||
removeDocumentEvent('keyup')
|
||||
// [TMP-DEL 2026-05-07] keyup 은 객체선택 useEffect 가 lifecycle 관리. 여기서 지우면 wrappedKeyup 이 같이 날아감
|
||||
document.removeEventListener('click', handleClick)
|
||||
document.removeEventListener('click', handleOutsideClick)
|
||||
canvasProps?.upperCanvasEl.removeEventListener('contextmenu', handleContextMenu) //한번 노출 후 이벤트 삭제
|
||||
}
|
||||
}, [contextRef, contextMenuList, currentObject])
|
||||
|
||||
// [TMP-DEL 2026-05-07] 객체 선택 시 Del 키로 즉시 삭제. 메뉴 단축키(M/C 등)는 기존 handleKeyup 으로 위임.
|
||||
// input/textarea/contentEditable 포커스 중에는 무시.
|
||||
useEffect(() => {
|
||||
if (!currentObject) {
|
||||
removeDocumentEvent('keyup')
|
||||
return
|
||||
}
|
||||
const wrappedKeyup = (e) => {
|
||||
const el = document.activeElement
|
||||
if (el && (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA' || el.isContentEditable)) return
|
||||
if (e.key === 'Delete' || e.key === 'Backspace') {
|
||||
triggerDeleteRef.current()
|
||||
return
|
||||
}
|
||||
handleKeyupRef.current(e)
|
||||
}
|
||||
addDocumentEventListener('keyup', document, wrappedKeyup)
|
||||
return () => removeDocumentEvent('keyup')
|
||||
}, [currentObject])
|
||||
|
||||
return (
|
||||
<>
|
||||
{contextMenu.visible && (
|
||||
|
||||
@ -114,6 +114,24 @@ export function useContextMenu() {
|
||||
if (menu) handleClick(null, menu)
|
||||
}
|
||||
|
||||
// [TMP-DEL 2026-05-07] Del 키용: 현재 contextMenu 에서 삭제 메뉴를 찾아 실행
|
||||
// 매칭 규칙: id === 'remove' 또는 id 가 'Remove' 로 끝남 (단, 'wallLineRemove' 제외, 'RemoveAll' 제외)
|
||||
const triggerDelete = () => {
|
||||
let target = null
|
||||
for (const group of contextMenu) {
|
||||
for (const item of group) {
|
||||
const id = item?.id || ''
|
||||
if (id === 'wallLineRemove') continue
|
||||
if (id === 'remove' || id.endsWith('Remove')) {
|
||||
target = item
|
||||
break
|
||||
}
|
||||
}
|
||||
if (target) break
|
||||
}
|
||||
if (target?.fn) handleClick(null, target)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
currentMenuSetting()
|
||||
}, [gridColor, currentMenu])
|
||||
@ -132,8 +150,7 @@ export function useContextMenu() {
|
||||
[
|
||||
{
|
||||
id: 'dormerRemove',
|
||||
shortcut: ['d', 'D'],
|
||||
name: `${getMessage('contextmenu.remove')}(D)`,
|
||||
name: getMessage('contextmenu.remove'),
|
||||
fn: () => deleteObject(),
|
||||
},
|
||||
{
|
||||
@ -206,8 +223,7 @@ export function useContextMenu() {
|
||||
},
|
||||
{
|
||||
id: 'roofMaterialRemove',
|
||||
shortcut: ['d', 'D'],
|
||||
name: `${getMessage('contextmenu.remove')}(D)`,
|
||||
name: getMessage('contextmenu.remove'),
|
||||
fn: () => deleteObject(),
|
||||
},
|
||||
{
|
||||
@ -300,8 +316,7 @@ export function useContextMenu() {
|
||||
},
|
||||
{
|
||||
id: 'roofMaterialRemove',
|
||||
shortcut: ['d', 'D'],
|
||||
name: `${getMessage('contextmenu.remove')}(D)`,
|
||||
name: getMessage('contextmenu.remove'),
|
||||
fn: () => deleteObject(),
|
||||
},
|
||||
{
|
||||
@ -364,8 +379,7 @@ export function useContextMenu() {
|
||||
},
|
||||
{
|
||||
id: 'auxiliaryRemove',
|
||||
shortcut: ['d', 'D'],
|
||||
name: `${getMessage('contextmenu.auxiliary.remove')}(D)`,
|
||||
name: getMessage('contextmenu.auxiliary.remove'),
|
||||
fn: () => {
|
||||
if (!currentObject) return
|
||||
const roof = canvas.getObjects().filter((obj) => obj.id === currentObject.attributes.roofId)[0]
|
||||
@ -474,8 +488,7 @@ export function useContextMenu() {
|
||||
},
|
||||
{
|
||||
id: 'openingRemove',
|
||||
shortcut: ['d', 'D'],
|
||||
name: `${getMessage('contextmenu.remove')}(D)`,
|
||||
name: getMessage('contextmenu.remove'),
|
||||
fn: () => deleteObject(),
|
||||
},
|
||||
{
|
||||
@ -677,8 +690,7 @@ export function useContextMenu() {
|
||||
},
|
||||
{
|
||||
id: 'remove',
|
||||
shortcut: ['d', 'D'],
|
||||
name: `${getMessage('contextmenu.remove')}(D)`,
|
||||
name: getMessage('contextmenu.remove'),
|
||||
fn: () => deleteObject(),
|
||||
},
|
||||
{
|
||||
@ -973,5 +985,6 @@ export function useContextMenu() {
|
||||
setCurrentContextMenu,
|
||||
handleClick,
|
||||
handleKeyup,
|
||||
triggerDelete, // [TMP-DEL 2026-05-07]
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user